BitMagic-C++
bmdef.h
Go to the documentation of this file.
1 /*
2 Copyright(c) 2002-2017 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 
16 For more information please visit: http://bitmagic.io
17 */
18 
19 /*! \file bmdef.h
20  \brief Definitions(internal)
21 */
22 
23 #include <climits>
24 
25 // Incorporate appropriate tuneups when the NCBI C++ Toolkit's core
26 // headers have been included.
27 //
28 #ifdef NCBI_ASSERT
29 # define BM_ASSERT _ASSERT
30 
31 # ifdef HAVE_RESTRICT_CXX
32 # define BM_HASRESTRICT
33 # define BMRESTRICT NCBI_RESTRICT
34 # endif
35 
36 # if defined(NCBI_FORCEINLINE) && \
37  ( !defined(NCBI_COMPILER_GCC) || NCBI_COMPILER_VERSION >= 400 || \
38  defined(__OPTIMIZE__))
39 # define BM_HASFORCEINLINE
40 # define BMFORCEINLINE NCBI_FORCEINLINE
41 # endif
42 
43 # ifdef NCBI_SSE
44 # if NCBI_SSE >= 20
45 # define BMSSE2OPT 1
46 # endif
47 # if NCBI_SSE >= 40
48 # define BMSSE2OPT 1
49 # endif
50 # if NCBI_SSE >= 42
51 # define BMSSE42OPT 1
52 # endif
53 # endif
54 #endif
55 
56 
57 // macro to define/undefine unaligned memory access (x86, PowerPC)
58 //
59 #if defined(__i386) || defined(__x86_64) || defined(__ppc__) || \
60  defined(__ppc64__) || defined(_M_IX86) || defined(_M_AMD64) || \
61  defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
62  (defined(_M_MPPC) && !defined(BM_FORBID_UNALIGNED_ACCESS))
63 #define BM_UNALIGNED_ACCESS_OK 1
64 #endif
65 
66 #if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \
67  defined(__i386) || defined(__x86_64) || defined(_M_AMD64) || \
68  defined(BMSSE2OPT) || defined(BMSSE42OPT)
69 #define BM_x86
70 #endif
71 
72 // cxx11 features
73 //
74 #if defined(BM_NO_CXX11) || (defined(_MSC_VER) && _MSC_VER < 1900)
75 # define BMNOEXEPT
76 #else
77 # ifndef BMNOEXEPT
78 # define BMNOEXEPT noexcept
79 # endif
80 #endif
81 
82 
83 // disable 'register' keyword, which is obsolete in C++11
84 //
85 #ifndef BMREGISTER
86 # define BMREGISTER
87 #endif
88 
89 
90 // Enable MSVC 8.0 (2005) specific optimization options
91 //
92 #if(_MSC_VER >= 1400)
93 
94 # define BM_HASFORCEINLINE
95 # ifndef BMRESTRICT
96 # define BMRESTRICT __restrict
97 # endif
98 #endif
99 
100 #ifdef __GNUG__
101 
102 # ifndef BMRESTRICT
103 # define BMRESTRICT __restrict__
104 # endif
105 
106 # ifdef __OPTIMIZE__
107 # define BM_NOASSERT
108 # endif
109 #endif
110 
111 
112 #ifndef BM_ASSERT
113 
114 # ifndef BM_NOASSERT
115 # include <cassert>
116 # define BM_ASSERT assert
117 # else
118 # ifndef BM_ASSERT
119 # define BM_ASSERT(x)
120 # endif
121 # endif
122 
123 #endif
124 
125 
126 #if defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
127  defined(__LP64__) || defined(_LP64) || ( __WORDSIZE == 64 )
128 #ifndef BM64OPT
129 # define BM64OPT
130 #endif
131 #endif
132 
133 
134 
135 #define FULL_BLOCK_REAL_ADDR bm::all_set<true>::_block._p
136 #define FULL_BLOCK_FAKE_ADDR bm::all_set<true>::_block._p_fullp
137 #define BLOCK_ADDR_SAN(addr) (addr == FULL_BLOCK_FAKE_ADDR) ? FULL_BLOCK_REAL_ADDR : addr
138 #define IS_VALID_ADDR(addr) bm::all_set<true>::is_valid_block_addr(addr)
139 #define IS_FULL_BLOCK(addr) bm::all_set<true>::is_full_block(addr)
140 #define IS_EMPTY_BLOCK(addr) bool(addr == 0)
141 
142 #define BM_BLOCK_TYPE(addr) bm::all_set<true>::block_type(addr)
143 
144 // Macro definitions to manipulate bits in pointers
145 // This trick is based on the fact that pointers allocated by malloc are
146 // aligned and bit 0 is never set. It means we are safe to use it.
147 // BM library keeps GAP flag in pointer.
148 
149 
150 
151 # if ULONG_MAX != 0xffffffff || defined(_WIN64) // 64-bit
152 
153 # define BMPTR_SETBIT0(ptr) ( ((bm::id64_t)ptr) | 1 )
154 # define BMPTR_CLEARBIT0(ptr) ( ((bm::id64_t)ptr) & ~(bm::id64_t)1 )
155 # define BMPTR_TESTBIT0(ptr) ( ((bm::id64_t)ptr) & 1 )
156 
157 # else // 32-bit
158 
159 # define BMPTR_SETBIT0(ptr) ( ((bm::id_t)ptr) | 1 )
160 # define BMPTR_CLEARBIT0(ptr) ( ((bm::id_t)ptr) & ~(bm::id_t)1 )
161 # define BMPTR_TESTBIT0(ptr) ( ((bm::id_t)ptr) & 1 )
162 
163 # endif
164 
165 # define BMGAP_PTR(ptr) ((bm::gap_word_t*)BMPTR_CLEARBIT0(ptr))
166 # define BMSET_PTRGAP(ptr) ptr = (bm::word_t*)BMPTR_SETBIT0(ptr)
167 # define BM_IS_GAP(ptr) bool(BMPTR_TESTBIT0(ptr)!=0)
168 
169 
170 
171 
172 
173 #ifdef BM_HASRESTRICT
174 # ifndef BMRESTRICT
175 # define BMRESTRICT restrict
176 # endif
177 #else
178 # ifndef BMRESTRICT
179 # define BMRESTRICT
180 # endif
181 #endif
182 
183 
184 #ifdef BM_HASFORCEINLINE
185 # ifndef BMFORCEINLINE
186 # define BMFORCEINLINE __forceinline
187 # endif
188 #else
189 # define BMFORCEINLINE inline
190 #endif
191 
192 
193 // --------------------------------
194 // SSE optmization macros
195 //
196 
197 #ifdef BMSSE42OPT
198 # if defined(BM64OPT) || defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
199  defined(__LP64__) || defined(_LP64)
200 # undef BM64OPT
201 # define BM64_SSE4
202 # endif
203 # undef BMSSE2OPT
204 #endif
205 
206 #ifdef BMAVX2OPT
207 # if defined(BM64OPT) || defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
208  defined(__LP64__) || defined(_LP64)
209 # undef BM64OPT
210 # undef BM64_SSE4
211 # define BM64_AVX2
212 # endif
213 # undef BMSSE2OPT
214 # undef BMSSE42OPT
215 #endif
216 
217 #ifdef BMAVX512OPT
218 # if defined(BM64OPT) || defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
219  defined(__LP64__) || defined(_LP64)
220 # undef BM64OPT
221 # undef BM64_SSE4
222 # undef BM64_AVX2
223 # define BM64_AVX512
224 # endif
225 # undef BMSSE2OPT
226 # undef BMSSE42OPT
227 #endif
228 
229 
230 
231 # ifndef BM_SET_MMX_GUARD
232 # define BM_SET_MMX_GUARD
233 # endif
234 
235 
236 #if !(defined(BMSSE2OPT) || defined(BMSSE42OPT) || defined(BMAVX2OPT) || defined(BMAVX512OPT))
237 
238 
239 #define BM_ALIGN16
240 #define BM_ALIGN16ATTR
241 #define BM_ALIGN32
242 #define BM_ALIGN32ATTR
243 #define BM_ALIGN64
244 #define BM_ALIGN64ATTR
245 
246 #else
247 
248 # ifndef BM_SET_MMX_GUARD
249 # define BM_SET_MMX_GUARD sse_empty_guard bm_mmx_guard_;
250 # endif
251 
252 #ifdef _MSC_VER
253 
254 #ifndef BM_ALIGN16
255 # define BM_ALIGN16 __declspec(align(16))
256 # define BM_ALIGN16ATTR
257 #endif
258 
259 #ifndef BM_ALIGN32
260 # define BM_ALIGN32 __declspec(align(32))
261 # define BM_ALIGN32ATTR
262 #endif
263 
264 #ifndef BM_ALIGN64
265 # define BM_ALIGN64 __declspec(align(64))
266 # define BM_ALIGN64ATTR
267 #endif
268 
269 
270 # else // GCC
271 
272 #ifndef BM_ALIGN16
273 # define BM_ALIGN16
274 # define BM_ALIGN16ATTR __attribute__((aligned(16)))
275 #endif
276 
277 #ifndef BM_ALIGN32
278 # define BM_ALIGN32
279 # define BM_ALIGN32ATTR __attribute__((aligned(32)))
280 #endif
281 
282 #ifndef BM_ALIGN64
283 # define BM_ALIGN64
284 # define BM_ALIGN64ATTR __attribute__((aligned(64)))
285 #endif
286 
287 
288 #endif
289 
290 #endif
291 
292 #if (defined(BMSSE2OPT) || defined(BMSSE42OPT))
293 # define BM_VECT_ALIGN BM_ALIGN16
294 # define BM_VECT_ALIGN_ATTR BM_ALIGN16ATTR
295 #else
296 # if defined(BMAVX2OPT)
297 # define BM_VECT_ALIGN BM_ALIGN32
298 # define BM_VECT_ALIGN_ATTR BM_ALIGN32ATTR
299 # else
300 # if defined(BMAVX512OPT)
301 # define BM_VECT_ALIGN BM_ALIGN64
302 # define BM_VECT_ALIGN_ATTR BM_ALIGN64ATTR
303 # else
304 # define BM_VECT_ALIGN
305 # define BM_VECT_ALIGN_ATTR
306 # endif
307 # endif
308 #endif
309 
310 
311 
312 
313 /*!
314  Define calculates number of 1 bits in 32-bit word.
315  @ingroup bitfunc
316 */
317 #ifndef BM_INCWORD_BITCOUNT
318 
319 #if (defined(BMSSE42OPT) || defined(BMAVX2OPT) || defined(BMAVX512OPT))
320 # define BM_INCWORD_BITCOUNT(cnt, w) cnt += unsigned(_mm_popcnt_u32(w));
321 #else
322 
323 # define BM_INCWORD_BITCOUNT(cnt, w) cnt += \
324  bm::bit_count_table<true>::_count[(unsigned char)(w)] + \
325  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 8)] + \
326  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 16)] + \
327  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 24)];
328 
329 
330 #endif
331 
332 // throw redefinintion for compatibility with language wrappers
333 //
334 #ifndef BM_ASSERT_THROW
335 #define BM_ASSERT_THROW(x, xerrcode)
336 #endif
337 
338 
339 
340 #endif
341 
342