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 # define BM_HASFORCEINLINE
94 # ifndef BMRESTRICT
95 # define BMRESTRICT __restrict
96 # endif
97 #endif
98 
99 #ifdef __GNUG__
100 # ifndef BMRESTRICT
101 # define BMRESTRICT __restrict__
102 # endif
103 
104 # ifdef __OPTIMIZE__
105 # define BM_NOASSERT
106 # endif
107 #endif
108 
109 # ifdef NDEBUG
110 # define BM_NOASSERT
111 # endif
112 
113 
114 #ifndef BM_ASSERT
115 # ifndef BM_NOASSERT
116 # include <cassert>
117 # define BM_ASSERT assert
118 # else
119 # ifndef BM_ASSERT
120 # define BM_ASSERT(x)
121 # endif
122 # endif
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 FULL_SUB_BLOCK_REAL_ADDR bm::all_set<true>::_block._s
138 #define BLOCK_ADDR_SAN(addr) (addr == FULL_BLOCK_FAKE_ADDR) ? FULL_BLOCK_REAL_ADDR : addr
139 #define IS_VALID_ADDR(addr) bm::all_set<true>::is_valid_block_addr(addr)
140 #define IS_FULL_BLOCK(addr) bm::all_set<true>::is_full_block(addr)
141 #define IS_EMPTY_BLOCK(addr) bool(addr == 0)
142 
143 #define BM_BLOCK_TYPE(addr) bm::all_set<true>::block_type(addr)
144 
145 // Macro definitions to manipulate bits in pointers
146 // This trick is based on the fact that pointers allocated by malloc are
147 // aligned and bit 0 is never set. It means we are safe to use it.
148 // BM library keeps GAP flag in pointer.
149 
150 
151 
152 # if ULONG_MAX != 0xffffffff || defined(_WIN64) // 64-bit
153 
154 # define BMPTR_SETBIT0(ptr) ( ((bm::id64_t)ptr) | 1 )
155 # define BMPTR_CLEARBIT0(ptr) ( ((bm::id64_t)ptr) & ~(bm::id64_t)1 )
156 # define BMPTR_TESTBIT0(ptr) ( ((bm::id64_t)ptr) & 1 )
157 
158 # else // 32-bit
159 
160 # define BMPTR_SETBIT0(ptr) ( ((bm::id_t)ptr) | 1 )
161 # define BMPTR_CLEARBIT0(ptr) ( ((bm::id_t)ptr) & ~(bm::id_t)1 )
162 # define BMPTR_TESTBIT0(ptr) ( ((bm::id_t)ptr) & 1 )
163 
164 # endif
165 
166 # define BMGAP_PTR(ptr) ((bm::gap_word_t*)BMPTR_CLEARBIT0(ptr))
167 # define BMSET_PTRGAP(ptr) ptr = (bm::word_t*)BMPTR_SETBIT0(ptr)
168 # define BM_IS_GAP(ptr) bool(BMPTR_TESTBIT0(ptr)!=0)
169 
170 
171 
172 
173 
174 #ifdef BM_HASRESTRICT
175 # ifndef BMRESTRICT
176 # define BMRESTRICT restrict
177 # endif
178 #else
179 # ifndef BMRESTRICT
180 # define BMRESTRICT
181 # endif
182 #endif
183 
184 
185 #ifdef BM_HASFORCEINLINE
186 # ifndef BMFORCEINLINE
187 # define BMFORCEINLINE __forceinline
188 # endif
189 #else
190 # define BMFORCEINLINE inline
191 #endif
192 
193 
194 // --------------------------------
195 // SSE optmization macros
196 //
197 
198 #ifdef BMSSE42OPT
199 # if defined(BM64OPT) || defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
200  defined(__LP64__) || defined(_LP64)
201 # undef BM64OPT
202 # define BM64_SSE4
203 # endif
204 # undef BMSSE2OPT
205 #endif
206 
207 #ifdef BMAVX2OPT
208 # if defined(BM64OPT) || defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
209  defined(__LP64__) || defined(_LP64)
210 # undef BM64OPT
211 # undef BM64_SSE4
212 # define BM64_AVX2
213 # endif
214 # undef BMSSE2OPT
215 # undef BMSSE42OPT
216 #endif
217 
218 #ifdef BMAVX512OPT
219 # if defined(BM64OPT) || defined(__x86_64) || defined(_M_AMD64) || defined(_WIN64) || \
220  defined(__LP64__) || defined(_LP64)
221 # undef BM64OPT
222 # undef BM64_SSE4
223 # undef BM64_AVX2
224 # define BM64_AVX512
225 # endif
226 # undef BMSSE2OPT
227 # undef BMSSE42OPT
228 #endif
229 
230 
231 
232 # ifndef BM_SET_MMX_GUARD
233 # define BM_SET_MMX_GUARD
234 # endif
235 
236 
237 #if (defined(BMSSE2OPT) || defined(BMSSE42OPT) || defined(BMAVX2OPT) || defined(BMAVX512OPT))
238 
239  # ifndef BM_SET_MMX_GUARD
240  # define BM_SET_MMX_GUARD sse_empty_guard bm_mmx_guard_;
241  # endif
242 
243  #ifdef _MSC_VER
244 
245  #ifndef BM_ALIGN16
246  # define BM_ALIGN16 __declspec(align(16))
247  # define BM_ALIGN16ATTR
248  #endif
249 
250  #ifndef BM_ALIGN32
251  # define BM_ALIGN32 __declspec(align(32))
252  # define BM_ALIGN32ATTR
253  #endif
254 
255  #ifndef BM_ALIGN64
256  # define BM_ALIGN64 __declspec(align(64))
257  # define BM_ALIGN64ATTR
258  #endif
259 
260  # else // GCC
261 
262  #ifndef BM_ALIGN16
263  # define BM_ALIGN16
264  # define BM_ALIGN16ATTR __attribute__((aligned(16)))
265  #endif
266 
267  #ifndef BM_ALIGN32
268  # define BM_ALIGN32
269  # define BM_ALIGN32ATTR __attribute__((aligned(32)))
270  #endif
271 
272  #ifndef BM_ALIGN64
273  # define BM_ALIGN64
274  # define BM_ALIGN64ATTR __attribute__((aligned(64)))
275  #endif
276  #endif
277 
278 #else
279 
280  #define BM_ALIGN16
281  #define BM_ALIGN16ATTR
282  #define BM_ALIGN32
283  #define BM_ALIGN32ATTR
284  #define BM_ALIGN64
285  #define BM_ALIGN64ATTR
286 
287 #endif
288 
289 
290 /*
291 #if !(defined(BMSSE2OPT) || defined(BMSSE42OPT) || defined(BMAVX2OPT) || defined(BMAVX512OPT))
292 
293  #define BM_ALIGN16
294  #define BM_ALIGN16ATTR
295  #define BM_ALIGN32
296  #define BM_ALIGN32ATTR
297  #define BM_ALIGN64
298  #define BM_ALIGN64ATTR
299 
300 #else
301 
302  # ifndef BM_SET_MMX_GUARD
303  # define BM_SET_MMX_GUARD sse_empty_guard bm_mmx_guard_;
304  # endif
305 
306  #ifdef _MSC_VER
307 
308  #ifndef BM_ALIGN16
309  # define BM_ALIGN16 __declspec(align(16))
310  # define BM_ALIGN16ATTR
311  #endif
312 
313  #ifndef BM_ALIGN32
314  # define BM_ALIGN32 __declspec(align(32))
315  # define BM_ALIGN32ATTR
316  #endif
317 
318  #ifndef BM_ALIGN64
319  # define BM_ALIGN64 __declspec(align(64))
320  # define BM_ALIGN64ATTR
321  #endif
322 
323  # else // GCC
324 
325  #ifndef BM_ALIGN16
326  # define BM_ALIGN16
327  # define BM_ALIGN16ATTR __attribute__((aligned(16)))
328  #endif
329 
330  #ifndef BM_ALIGN32
331  # define BM_ALIGN32
332  # define BM_ALIGN32ATTR __attribute__((aligned(32)))
333  #endif
334 
335  #ifndef BM_ALIGN64
336  # define BM_ALIGN64
337  # define BM_ALIGN64ATTR __attribute__((aligned(64)))
338  #endif
339  #endif
340 
341 #endif
342 */
343 
344 
345 #if (defined(BMSSE2OPT) || defined(BMSSE42OPT))
346 # define BM_VECT_ALIGN BM_ALIGN16
347 # define BM_VECT_ALIGN_ATTR BM_ALIGN16ATTR
348 #else
349 # if defined(BMAVX2OPT)
350 # define BM_VECT_ALIGN BM_ALIGN32
351 # define BM_VECT_ALIGN_ATTR BM_ALIGN32ATTR
352 # else
353 # if defined(BMAVX512OPT)
354 # define BM_VECT_ALIGN BM_ALIGN64
355 # define BM_VECT_ALIGN_ATTR BM_ALIGN64ATTR
356 # else
357 # define BM_VECT_ALIGN
358 # define BM_VECT_ALIGN_ATTR
359 # endif
360 # endif
361 #endif
362 
363 
364 
365 
366 /*!
367  Define calculates number of 1 bits in 32-bit word.
368  @ingroup bitfunc
369 */
370 #ifndef BM_INCWORD_BITCOUNT
371 
372 #if (defined(BMSSE42OPT) || defined(BMAVX2OPT) || defined(BMAVX512OPT))
373 # define BM_INCWORD_BITCOUNT(cnt, w) cnt += unsigned(_mm_popcnt_u32(w));
374 #else
375 
376 # define BM_INCWORD_BITCOUNT(cnt, w) cnt += \
377  bm::bit_count_table<true>::_count[(unsigned char)(w)] + \
378  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 8)] + \
379  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 16)] + \
380  bm::bit_count_table<true>::_count[(unsigned char)((w) >> 24)];
381 
382 
383 #endif
384 
385 // throw redefinintion for compatibility with language wrappers
386 //
387 #ifndef BM_ASSERT_THROW
388 #define BM_ASSERT_THROW(x, xerrcode)
389 #endif
390 
391 
392 
393 #endif
394 
395