• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _DEINT32_H
2 #define _DEINT32_H
3 /*-------------------------------------------------------------------------
4  * drawElements Base Portability Library
5  * -------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief 32-bit integer math.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "deDefs.h"
27 
28 #if (DE_COMPILER == DE_COMPILER_MSC)
29 #	include <intrin.h>
30 #endif
31 
32 DE_BEGIN_EXTERN_C
33 
34 enum
35 {
36 	DE_RCP_FRAC_BITS	= 30		/*!< Number of fractional bits in deRcp32() result. */
37 };
38 
39 void	deRcp32				(deUint32 a, deUint32* rcp, int* exp);
40 void	deInt32_computeLUTs	(void);
41 void	deInt32_selfTest	(void);
42 
43 /*--------------------------------------------------------------------*//*!
44  * \brief Compute the absolute of an int.
45  * \param a	Input value.
46  * \return Absolute of the input value.
47  *
48  * \note The input 0x80000000u (for which the abs value cannot be
49  * represented), is asserted and returns the value itself.
50  *//*--------------------------------------------------------------------*/
deAbs32(int a)51 DE_INLINE int deAbs32 (int a)
52 {
53 	DE_ASSERT((unsigned int) a != 0x80000000u);
54 	return (a < 0) ? -a : a;
55 }
56 
57 /*--------------------------------------------------------------------*//*!
58  * \brief Compute the signed minimum of two values.
59  * \param a	First input value.
60  * \param b Second input value.
61  * \return The smallest of the two input values.
62  *//*--------------------------------------------------------------------*/
deMin32(int a,int b)63 DE_INLINE int deMin32 (int a, int b)
64 {
65 	return (a <= b) ? a : b;
66 }
67 
68 /*--------------------------------------------------------------------*//*!
69  * \brief Compute the signed maximum of two values.
70  * \param a	First input value.
71  * \param b Second input value.
72  * \return The largest of the two input values.
73  *//*--------------------------------------------------------------------*/
deMax32(int a,int b)74 DE_INLINE int deMax32 (int a, int b)
75 {
76 	return (a >= b) ? a : b;
77 }
78 
79 /*--------------------------------------------------------------------*//*!
80  * \brief Compute the unsigned minimum of two values.
81  * \param a	First input value.
82  * \param b Second input value.
83  * \return The smallest of the two input values.
84  *//*--------------------------------------------------------------------*/
deMinu32(deUint32 a,deUint32 b)85 DE_INLINE deUint32 deMinu32 (deUint32 a, deUint32 b)
86 {
87 	return (a <= b) ? a : b;
88 }
89 
90 /*--------------------------------------------------------------------*//*!
91  * \brief Compute the unsigned minimum of two values.
92  * \param a	First input value.
93  * \param b Second input value.
94  * \return The smallest of the two input values.
95  *//*--------------------------------------------------------------------*/
deMinu64(deUint64 a,deUint64 b)96 DE_INLINE deUint64 deMinu64 (deUint64 a, deUint64 b)
97 {
98 	return (a <= b) ? a : b;
99 }
100 
101 /*--------------------------------------------------------------------*//*!
102  * \brief Compute the unsigned maximum of two values.
103  * \param a	First input value.
104  * \param b Second input value.
105  * \return The largest of the two input values.
106  *//*--------------------------------------------------------------------*/
deMaxu32(deUint32 a,deUint32 b)107 DE_INLINE deUint32 deMaxu32 (deUint32 a, deUint32 b)
108 {
109 	return (a >= b) ? a : b;
110 }
111 
112 /*--------------------------------------------------------------------*//*!
113  * \brief Check if a value is in the <b>inclusive<b> range [mn, mx].
114  * \param a		Value to check for range.
115  * \param mn	Range minimum value.
116  * \param mx	Range maximum value.
117  * \return True if (a >= mn) and (a <= mx), false otherwise.
118  *
119  * \see deInBounds32()
120  *//*--------------------------------------------------------------------*/
deInRange32(int a,int mn,int mx)121 DE_INLINE deBool deInRange32 (int a, int mn, int mx)
122 {
123 	return (a >= mn) && (a <= mx);
124 }
125 
126 /*--------------------------------------------------------------------*//*!
127  * \brief Check if a value is in the half-inclusive bounds [mn, mx[.
128  * \param a		Value to check for range.
129  * \param mn	Range minimum value.
130  * \param mx	Range maximum value.
131  * \return True if (a >= mn) and (a < mx), false otherwise.
132  *
133  * \see deInRange32()
134  *//*--------------------------------------------------------------------*/
deInBounds32(int a,int mn,int mx)135 DE_INLINE deBool deInBounds32 (int a, int mn, int mx)
136 {
137 	return (a >= mn) && (a < mx);
138 }
139 
140 /*--------------------------------------------------------------------*//*!
141  * \brief Clamp a value into the range [mn, mx].
142  * \param a		Value to clamp.
143  * \param mn	Minimum value.
144  * \param mx	Maximum value.
145  * \return The clamped value in [mn, mx] range.
146  *//*--------------------------------------------------------------------*/
deClamp32(int a,int mn,int mx)147 DE_INLINE int deClamp32 (int a, int mn, int mx)
148 {
149 	DE_ASSERT(mn <= mx);
150 	if (a < mn) return mn;
151 	if (a > mx) return mx;
152 	return a;
153 }
154 
155 /*--------------------------------------------------------------------*//*!
156  * \brief Get the sign of an integer.
157  * \param a	Input value.
158  * \return +1 if a>0, 0 if a==0, -1 if a<0.
159  *//*--------------------------------------------------------------------*/
deSign32(int a)160 DE_INLINE int deSign32 (int a)
161 {
162 	if (a > 0) return +1;
163 	if (a < 0) return -1;
164 	return 0;
165 }
166 
167 /*--------------------------------------------------------------------*//*!
168  * \brief Extract the sign bit of a.
169  * \param a	Input value.
170  * \return 0x80000000 if a<0, 0 otherwise.
171  *//*--------------------------------------------------------------------*/
deSignBit32(deInt32 a)172 DE_INLINE deInt32 deSignBit32 (deInt32 a)
173 {
174 	return (deInt32)((deUint32)a & 0x80000000u);
175 }
176 
177 /*--------------------------------------------------------------------*//*!
178  * \brief Integer rotate right.
179  * \param val	Value to rotate.
180  * \param r		Number of bits to rotate (in range [0, 32]).
181  * \return The rotated value.
182  *//*--------------------------------------------------------------------*/
deRor32(int val,int r)183 DE_INLINE int deRor32 (int val, int r)
184 {
185 	DE_ASSERT(r >= 0 && r <= 32);
186 	if (r == 0 || r == 32)
187 		return val;
188 	else
189 		return (int)(((deUint32)val >> r) | ((deUint32)val << (32-r)));
190 }
191 
192 /*--------------------------------------------------------------------*//*!
193  * \brief Integer rotate left.
194  * \param val	Value to rotate.
195  * \param r		Number of bits to rotate (in range [0, 32]).
196  * \return The rotated value.
197  *//*--------------------------------------------------------------------*/
deRol32(int val,int r)198 DE_INLINE int deRol32 (int val, int r)
199 {
200 	DE_ASSERT(r >= 0 && r <= 32);
201 	if (r == 0 || r == 32)
202 		return val;
203 	else
204 		return (int)(((deUint32)val << r) | ((deUint32)val >> (32-r)));
205 }
206 
207 /*--------------------------------------------------------------------*//*!
208  * \brief Check if a value is a power-of-two.
209  * \param a Input value.
210  * \return True if input is a power-of-two value, false otherwise.
211  *
212  * \note Also returns true for zero.
213  *//*--------------------------------------------------------------------*/
deIsPowerOfTwo32(int a)214 DE_INLINE deBool deIsPowerOfTwo32 (int a)
215 {
216 	return ((a & (a - 1)) == 0);
217 }
218 
219 /*--------------------------------------------------------------------*//*!
220  * \brief Check if a value is a power-of-two.
221  * \param a Input value.
222  * \return True if input is a power-of-two value, false otherwise.
223  *
224  * \note Also returns true for zero.
225  *//*--------------------------------------------------------------------*/
deIsPowerOfTwo64(deUint64 a)226 DE_INLINE deBool deIsPowerOfTwo64 (deUint64 a)
227 {
228 	return ((a & (a - 1ull)) == 0);
229 }
230 
231 /*--------------------------------------------------------------------*//*!
232  * \brief Check if a value is a power-of-two.
233  * \param a Input value.
234  * \return True if input is a power-of-two value, false otherwise.
235  *
236  * \note Also returns true for zero.
237  *//*--------------------------------------------------------------------*/
deIsPowerOfTwoSize(size_t a)238 DE_INLINE deBool deIsPowerOfTwoSize (size_t a)
239 {
240 #if (DE_PTR_SIZE == 4)
241 	return deIsPowerOfTwo32(a);
242 #elif (DE_PTR_SIZE == 8)
243 	return deIsPowerOfTwo64(a);
244 #else
245 #	error "Invalid DE_PTR_SIZE"
246 #endif
247 }
248 
249 /*--------------------------------------------------------------------*//*!
250  * \brief Roud a value up to a power-of-two.
251  * \param a Input value.
252  * \return Smallest power-of-two value that is greater or equal to an input value.
253  *//*--------------------------------------------------------------------*/
deSmallestGreaterOrEquallPowerOfTwoU32(deUint32 a)254 DE_INLINE deUint32 deSmallestGreaterOrEquallPowerOfTwoU32 (deUint32 a)
255 {
256 	--a;
257 	a |= a >> 1u;
258 	a |= a >> 2u;
259 	a |= a >> 4u;
260 	a |= a >> 8u;
261 	a |= a >> 16u;
262 	return ++a;
263 }
264 
265 /*--------------------------------------------------------------------*//*!
266  * \brief Roud a value up to a power-of-two.
267  * \param a Input value.
268  * \return Smallest power-of-two value that is greater or equal to an input value.
269  *//*--------------------------------------------------------------------*/
deSmallestGreaterOrEquallPowerOfTwoU64(deUint64 a)270 DE_INLINE deUint64 deSmallestGreaterOrEquallPowerOfTwoU64 (deUint64 a)
271 {
272 	--a;
273 	a |= a >> 1u;
274 	a |= a >> 2u;
275 	a |= a >> 4u;
276 	a |= a >> 8u;
277 	a |= a >> 16u;
278 	a |= a >> 32u;
279 	return ++a;
280 }
281 
282 /*--------------------------------------------------------------------*//*!
283  * \brief Roud a value up to a power-of-two.
284  * \param a Input value.
285  * \return Smallest power-of-two value that is greater or equal to an input value.
286  *//*--------------------------------------------------------------------*/
deSmallestGreaterOrEquallPowerOfTwoSize(size_t a)287 DE_INLINE size_t deSmallestGreaterOrEquallPowerOfTwoSize (size_t a)
288 {
289 #if (DE_PTR_SIZE == 4)
290 	return deSmallestGreaterOrEquallPowerOfTwoU32(a);
291 #elif (DE_PTR_SIZE == 8)
292 	return deSmallestGreaterOrEquallPowerOfTwoU64(a);
293 #else
294 #	error "Invalid DE_PTR_SIZE"
295 #endif
296 }
297 
298 /*--------------------------------------------------------------------*//*!
299  * \brief Check if an integer is aligned to given power-of-two size.
300  * \param a		Input value.
301  * \param align	Alignment to check for.
302  * \return True if input is aligned, false otherwise.
303  *//*--------------------------------------------------------------------*/
deIsAligned32(int a,int align)304 DE_INLINE deBool deIsAligned32 (int a, int align)
305 {
306 	DE_ASSERT(deIsPowerOfTwo32(align));
307 	return ((a & (align-1)) == 0);
308 }
309 
310 /*--------------------------------------------------------------------*//*!
311  * \brief Check if an integer is aligned to given power-of-two size.
312  * \param a		Input value.
313  * \param align	Alignment to check for.
314  * \return True if input is aligned, false otherwise.
315  *//*--------------------------------------------------------------------*/
deIsAligned64(deInt64 a,deInt64 align)316 DE_INLINE deBool deIsAligned64 (deInt64 a, deInt64 align)
317 {
318 	DE_ASSERT(deIsPowerOfTwo64(align));
319 	return ((a & (align-1)) == 0);
320 }
321 
322 /*--------------------------------------------------------------------*//*!
323  * \brief Check if a pointer is aligned to given power-of-two size.
324  * \param ptr	Input pointer.
325  * \param align	Alignment to check for (power-of-two).
326  * \return True if input is aligned, false otherwise.
327  *//*--------------------------------------------------------------------*/
deIsAlignedPtr(const void * ptr,deUintptr align)328 DE_INLINE deBool deIsAlignedPtr (const void* ptr, deUintptr align)
329 {
330 	DE_ASSERT((align & (align-1)) == 0); /* power of two */
331 	return (((deUintptr)ptr & (align-1)) == 0);
332 }
333 
334 /*--------------------------------------------------------------------*//*!
335  * \brief Align an integer to given power-of-two size.
336  * \param val	Input to align.
337  * \param align	Alignment to check for (power-of-two).
338  * \return The aligned value (larger or equal to input).
339  *//*--------------------------------------------------------------------*/
deAlign32(deInt32 val,deInt32 align)340 DE_INLINE deInt32 deAlign32 (deInt32 val, deInt32 align)
341 {
342 	DE_ASSERT(deIsPowerOfTwo32(align));
343 	return (val + align - 1) & ~(align - 1);
344 }
345 
346 /*--------------------------------------------------------------------*//*!
347  * \brief Align an integer to given power-of-two size.
348  * \param val	Input to align.
349  * \param align	Alignment to check for (power-of-two).
350  * \return The aligned value (larger or equal to input).
351  *//*--------------------------------------------------------------------*/
deAlign64(deInt64 val,deInt64 align)352 DE_INLINE deInt64 deAlign64 (deInt64 val, deInt64 align)
353 {
354 	DE_ASSERT(deIsPowerOfTwo64(align));
355 	return (val + align - 1) & ~(align - 1);
356 }
357 
358 /*--------------------------------------------------------------------*//*!
359  * \brief Align a pointer to given power-of-two size.
360  * \param ptr	Input pointer to align.
361  * \param align	Alignment to check for (power-of-two).
362  * \return The aligned pointer (larger or equal to input).
363  *//*--------------------------------------------------------------------*/
deAlignPtr(void * ptr,deUintptr align)364 DE_INLINE void* deAlignPtr (void* ptr, deUintptr align)
365 {
366 	deUintptr val = (deUintptr)ptr;
367 	DE_ASSERT((align & (align-1)) == 0); /* power of two */
368 	return (void*)((val + align - 1) & ~(align - 1));
369 }
370 
371 /*--------------------------------------------------------------------*//*!
372  * \brief Align a size_t value to given power-of-two size.
373  * \param ptr	Input value to align.
374  * \param align	Alignment to check for (power-of-two).
375  * \return The aligned size (larger or equal to input).
376  *//*--------------------------------------------------------------------*/
deAlignSize(size_t val,size_t align)377 DE_INLINE size_t deAlignSize (size_t val, size_t align)
378 {
379 	DE_ASSERT(deIsPowerOfTwoSize(align));
380 	return (val + align - 1) & ~(align - 1);
381 }
382 
383 extern const deInt8 g_clzLUT[256];
384 
385 /*--------------------------------------------------------------------*//*!
386  * \brief Compute number of leading zeros in an integer.
387  * \param a	Input value.
388  * \return The number of leading zero bits in the input.
389  *//*--------------------------------------------------------------------*/
deClz32(deUint32 a)390 DE_INLINE int deClz32 (deUint32 a)
391 {
392 #if (DE_COMPILER == DE_COMPILER_MSC)
393 	unsigned long i;
394 	if (_BitScanReverse(&i, (unsigned long)a) == 0)
395 		return 32;
396 	else
397 		return 31-i;
398 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
399 	if (a == 0)
400 		return 32;
401 	else
402 		return __builtin_clz((unsigned int)a);
403 #else
404 	if ((a & 0xFF000000u) != 0)
405 		return (int)g_clzLUT[a >> 24];
406 	if ((a & 0x00FF0000u) != 0)
407 		return 8 + (int)g_clzLUT[a >> 16];
408 	if ((a & 0x0000FF00u) != 0)
409 		return 16 + (int)g_clzLUT[a >> 8];
410 	return 24 + (int)g_clzLUT[a];
411 #endif
412 }
413 
414 extern const deInt8 g_ctzLUT[256];
415 
416 /*--------------------------------------------------------------------*//*!
417  * \brief Compute number of trailing zeros in an integer.
418  * \param a	Input value.
419  * \return The number of trailing zero bits in the input.
420  *//*--------------------------------------------------------------------*/
deCtz32(deUint32 a)421 DE_INLINE int deCtz32 (deUint32 a)
422 {
423 #if (DE_COMPILER == DE_COMPILER_MSC)
424 	unsigned long i;
425 	if (_BitScanForward(&i, (unsigned long)a) == 0)
426 		return 32;
427 	else
428 		return i;
429 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
430 	if (a == 0)
431 		return 32;
432 	else
433 		return __builtin_ctz((unsigned int)a);
434 #else
435 	if ((a & 0x00FFFFFFu) == 0)
436 		return (int)g_ctzLUT[a >> 24] + 24;
437 	if ((a & 0x0000FFFFu) == 0)
438 		return (int)g_ctzLUT[(a >> 16) & 0xffu] + 16;
439 	if ((a & 0x000000FFu) == 0)
440 		return (int)g_ctzLUT[(a >> 8) & 0xffu] + 8;
441 	return (int)g_ctzLUT[a & 0xffu];
442 #endif
443 }
444 
445 /*--------------------------------------------------------------------*//*!
446  * \brief Compute integer 'floor' of 'log2' for a positive integer.
447  * \param a	Input value.
448  * \return floor(log2(a)).
449  *//*--------------------------------------------------------------------*/
deLog2Floor32(deInt32 a)450 DE_INLINE int deLog2Floor32 (deInt32 a)
451 {
452 	DE_ASSERT(a > 0);
453 	return 31 - deClz32((deUint32)a);
454 }
455 
456 /*--------------------------------------------------------------------*//*!
457  * \brief Compute integer 'ceil' of 'log2' for a positive integer.
458  * \param a	Input value.
459  * \return ceil(log2(a)).
460  *//*--------------------------------------------------------------------*/
deLog2Ceil32(deInt32 a)461 DE_INLINE int deLog2Ceil32 (deInt32 a)
462 {
463 	int log2floor = deLog2Floor32(a);
464 	if (deIsPowerOfTwo32(a))
465 		return log2floor;
466 	else
467 		return log2floor+1;
468 }
469 
470 /*--------------------------------------------------------------------*//*!
471  * \brief Compute the bit population count of an integer.
472  * \param a	Input value.
473  * \return The number of one bits in the input.
474  *//*--------------------------------------------------------------------*/
dePop32(deUint32 a)475 DE_INLINE int dePop32 (deUint32 a)
476 {
477 	deUint32 mask0 = 0x55555555; /* 1-bit values. */
478 	deUint32 mask1 = 0x33333333; /* 2-bit values. */
479 	deUint32 mask2 = 0x0f0f0f0f; /* 4-bit values. */
480 	deUint32 mask3 = 0x00ff00ff; /* 8-bit values. */
481 	deUint32 mask4 = 0x0000ffff; /* 16-bit values. */
482 	deUint32 t = (deUint32)a;
483 	t = (t & mask0) + ((t>>1) & mask0);
484 	t = (t & mask1) + ((t>>2) & mask1);
485 	t = (t & mask2) + ((t>>4) & mask2);
486 	t = (t & mask3) + ((t>>8) & mask3);
487 	t = (t & mask4) + (t>>16);
488 	return (int)t;
489 }
490 
dePop64(deUint64 a)491 DE_INLINE int dePop64 (deUint64 a)
492 {
493 	return dePop32((deUint32)(a & 0xffffffffull)) + dePop32((deUint32)(a >> 32));
494 }
495 
496 /*--------------------------------------------------------------------*//*!
497  * \brief Reverse bytes in 32-bit integer (for example MSB -> LSB).
498  * \param a	Input value.
499  * \return The input with bytes reversed
500  *//*--------------------------------------------------------------------*/
deReverseBytes32(deUint32 v)501 DE_INLINE deUint32 deReverseBytes32 (deUint32 v)
502 {
503 	deUint32 b0 = v << 24;
504 	deUint32 b1 = (v & 0x0000ff00) << 8;
505 	deUint32 b2 = (v & 0x00ff0000) >> 8;
506 	deUint32 b3 = v >> 24;
507 	return b0|b1|b2|b3;
508 }
509 
510 /*--------------------------------------------------------------------*//*!
511  * \brief Reverse bytes in 16-bit integer (for example MSB -> LSB).
512  * \param a	Input value.
513  * \return The input with bytes reversed
514  *//*--------------------------------------------------------------------*/
deReverseBytes16(deUint16 v)515 DE_INLINE deUint16 deReverseBytes16 (deUint16 v)
516 {
517 	return (deUint16)((v << 8) | (v >> 8));
518 }
519 
deSafeMul32(deInt32 a,deInt32 b)520 DE_INLINE deInt32 deSafeMul32 (deInt32 a, deInt32 b)
521 {
522 	deInt32 res = a * b;
523 	DE_ASSERT((deInt64)res == ((deInt64)a * (deInt64)b));
524 	return res;
525 }
526 
deSafeAdd32(deInt32 a,deInt32 b)527 DE_INLINE deInt32 deSafeAdd32 (deInt32 a, deInt32 b)
528 {
529 	DE_ASSERT((deInt64)a + (deInt64)b == (deInt64)(a + b));
530 	return (a + b);
531 }
532 
deDivRoundUp32(deInt32 a,deInt32 b)533 DE_INLINE deInt32 deDivRoundUp32 (deInt32 a, deInt32 b)
534 {
535 	return a/b + ((a%b) ? 1 : 0);
536 }
537 
538 /* \todo [petri] Move to deInt64.h? */
539 
deMulAsr32(deInt32 a,deInt32 b,int shift)540 DE_INLINE deInt32 deMulAsr32 (deInt32 a, deInt32 b, int shift)
541 {
542 	return (deInt32)(((deInt64)a * (deInt64)b) >> shift);
543 }
544 
deSafeMulAsr32(deInt32 a,deInt32 b,int shift)545 DE_INLINE deInt32 deSafeMulAsr32 (deInt32 a, deInt32 b, int shift)
546 {
547 	deInt64 res = ((deInt64)a * (deInt64)b) >> shift;
548 	DE_ASSERT(res == (deInt64)(deInt32)res);
549 	return (deInt32)res;
550 }
551 
deSafeMuluAsr32(deUint32 a,deUint32 b,int shift)552 DE_INLINE deUint32 deSafeMuluAsr32 (deUint32 a, deUint32 b, int shift)
553 {
554 	deUint64 res = ((deUint64)a * (deUint64)b) >> shift;
555 	DE_ASSERT(res == (deUint64)(deUint32)res);
556 	return (deUint32)res;
557 }
558 
deMul32_32_64(deInt32 a,deInt32 b)559 DE_INLINE deInt64 deMul32_32_64 (deInt32 a, deInt32 b)
560 {
561 	return ((deInt64)a * (deInt64)b);
562 }
563 
deAbs64(deInt64 a)564 DE_INLINE deInt64 deAbs64 (deInt64 a)
565 {
566 	DE_ASSERT((deUint64) a != 0x8000000000000000LL);
567 	return (a >= 0) ? a : -a;
568 }
569 
deClz64(deUint64 a)570 DE_INLINE int deClz64 (deUint64 a)
571 {
572 	if ((a >> 32) != 0)
573 		return deClz32((deUint32)(a >> 32));
574 	return deClz32((deUint32)a) + 32;
575 }
576 
577 /* Common hash & compare functions. */
578 
deInt32Hash(deInt32 a)579 DE_INLINE deUint32 deInt32Hash (deInt32 a)
580 {
581 	/* From: http://www.concentric.net/~Ttwang/tech/inthash.htm */
582 	deUint32 key = (deUint32)a;
583 	key = (key ^ 61) ^ (key >> 16);
584 	key = key + (key << 3);
585 	key = key ^ (key >> 4);
586 	key = key * 0x27d4eb2d; /* prime/odd constant */
587 	key = key ^ (key >> 15);
588 	return key;
589 }
590 
deInt64Hash(deInt64 a)591 DE_INLINE deUint32 deInt64Hash (deInt64 a)
592 {
593 	/* From: http://www.concentric.net/~Ttwang/tech/inthash.htm */
594 	deUint64 key = (deUint64)a;
595 	key = (~key) + (key << 21); /* key = (key << 21) - key - 1; */
596 	key = key ^ (key >> 24);
597 	key = (key + (key << 3)) + (key << 8); /* key * 265 */
598 	key = key ^ (key >> 14);
599 	key = (key + (key << 2)) + (key << 4); /* key * 21 */
600 	key = key ^ (key >> 28);
601 	key = key + (key << 31);
602 	return (deUint32)key;
603 }
604 
deInt16Hash(deInt16 v)605 DE_INLINE deUint32	deInt16Hash		(deInt16 v)					{ return deInt32Hash(v);			}
deUint16Hash(deUint16 v)606 DE_INLINE deUint32	deUint16Hash	(deUint16 v)				{ return deInt32Hash((deInt32)v);	}
deUint32Hash(deUint32 v)607 DE_INLINE deUint32	deUint32Hash	(deUint32 v)				{ return deInt32Hash((deInt32)v);	}
deUint64Hash(deUint64 v)608 DE_INLINE deUint32	deUint64Hash	(deUint64 v)				{ return deInt64Hash((deInt64)v);	}
609 
deInt16Equal(deInt16 a,deInt16 b)610 DE_INLINE deBool	deInt16Equal	(deInt16 a, deInt16 b)		{ return (a == b);	}
deUint16Equal(deUint16 a,deUint16 b)611 DE_INLINE deBool	deUint16Equal	(deUint16 a, deUint16 b)	{ return (a == b);	}
deInt32Equal(deInt32 a,deInt32 b)612 DE_INLINE deBool	deInt32Equal	(deInt32 a, deInt32 b)		{ return (a == b);	}
deUint32Equal(deUint32 a,deUint32 b)613 DE_INLINE deBool	deUint32Equal	(deUint32 a, deUint32 b)	{ return (a == b);	}
deInt64Equal(deInt64 a,deInt64 b)614 DE_INLINE deBool	deInt64Equal	(deInt64 a, deInt64 b)		{ return (a == b);	}
deUint64Equal(deUint64 a,deUint64 b)615 DE_INLINE deBool	deUint64Equal	(deUint64 a, deUint64 b)	{ return (a == b);	}
616 
dePointerHash(const void * ptr)617 DE_INLINE deUint32	dePointerHash (const void* ptr)
618 {
619 	deUintptr val = (deUintptr)ptr;
620 #if (DE_PTR_SIZE == 4)
621 	return deInt32Hash((int)val);
622 #elif (DE_PTR_SIZE == 8)
623 	return deInt64Hash((deInt64)val);
624 #else
625 #	error Unsupported pointer size.
626 #endif
627 }
628 
dePointerEqual(const void * a,const void * b)629 DE_INLINE deBool dePointerEqual (const void* a, const void* b)
630 {
631 	return (a == b);
632 }
633 
634 /**
635  *	\brief	Modulo that generates the same sign as divisor and rounds toward
636  *			negative infinity -- assuming c99 %-operator.
637  */
deInt32ModF(deInt32 n,deInt32 d)638 DE_INLINE deInt32 deInt32ModF (deInt32 n, deInt32 d)
639 {
640 	deInt32 r = n%d;
641 	if ((r > 0 && d < 0) || (r < 0 && d > 0)) r = r+d;
642 	return r;
643 }
644 
deInt64InInt32Range(deInt64 x)645 DE_INLINE deBool deInt64InInt32Range (deInt64 x)
646 {
647 	return ((x >= (((deInt64)((deInt32)(-0x7FFFFFFF - 1))))) && (x <= ((1ll<<31)-1)));
648 }
649 
650 
deBitMask32(int leastSignificantBitNdx,int numBits)651 DE_INLINE deUint32 deBitMask32 (int leastSignificantBitNdx, int numBits)
652 {
653 	DE_ASSERT(deInRange32(leastSignificantBitNdx, 0, 32));
654 	DE_ASSERT(deInRange32(numBits, 0, 32));
655 	DE_ASSERT(deInRange32(leastSignificantBitNdx+numBits, 0, 32));
656 
657 	if (numBits < 32 && leastSignificantBitNdx < 32)
658 		return ((1u<<numBits)-1u) << (deUint32)leastSignificantBitNdx;
659 	else if (numBits == 0 && leastSignificantBitNdx == 32)
660 		return 0u;
661 	else
662 	{
663 		DE_ASSERT(numBits == 32 && leastSignificantBitNdx == 0);
664 		return 0xFFFFFFFFu;
665 	}
666 }
667 
deUintMaxValue32(int numBits)668 DE_INLINE deUint32 deUintMaxValue32 (int numBits)
669 {
670 	DE_ASSERT(deInRange32(numBits, 1, 32));
671 	if (numBits < 32)
672 		return ((1u<<numBits)-1u);
673 	else
674 		return 0xFFFFFFFFu;
675 }
676 
deIntMaxValue32(int numBits)677 DE_INLINE deInt32 deIntMaxValue32 (int numBits)
678 {
679 	DE_ASSERT(deInRange32(numBits, 1, 32));
680 	if (numBits < 32)
681 		return ((deInt32)1 << (numBits - 1)) - 1;
682 	else
683 	{
684 		/* avoid undefined behavior of int overflow when shifting */
685 		return 0x7FFFFFFF;
686 	}
687 }
688 
deIntMinValue32(int numBits)689 DE_INLINE deInt32 deIntMinValue32 (int numBits)
690 {
691 	DE_ASSERT(deInRange32(numBits, 1, 32));
692 	if (numBits < 32)
693 		return -((deInt32)1 << (numBits - 1));
694 	else
695 	{
696 		/* avoid undefined behavior of int overflow when shifting */
697 		return (deInt32)(-0x7FFFFFFF - 1);
698 	}
699 }
700 
deSignExtendTo32(deInt32 value,int numBits)701 DE_INLINE deInt32 deSignExtendTo32 (deInt32 value, int numBits)
702 {
703 	DE_ASSERT(deInRange32(numBits, 1, 32));
704 
705 	if (numBits < 32)
706 	{
707 		deBool		signSet		= ((deUint32)value & (1u<<(numBits-1))) != 0;
708 		deUint32	signMask	= deBitMask32(numBits, 32-numBits);
709 
710 		DE_ASSERT(((deUint32)value & signMask) == 0u);
711 
712 		return (deInt32)((deUint32)value | (signSet ? signMask : 0u));
713 	}
714 	else
715 		return value;
716 }
717 
deIntIsPow2(int powerOf2)718 DE_INLINE int deIntIsPow2(int powerOf2)
719 {
720 	if (powerOf2 <= 0)
721 		return 0;
722 	return (powerOf2 & (powerOf2 - (int)1)) == (int)0;
723 }
724 
deIntRoundToPow2(int number,int powerOf2)725 DE_INLINE int deIntRoundToPow2(int number, int powerOf2)
726 {
727 	DE_ASSERT(deIntIsPow2(powerOf2));
728 	return (number + (int)powerOf2 - (int)1) & (int)(~(powerOf2 - 1));
729 }
730 
731 
732 DE_END_EXTERN_C
733 
734 #endif /* _DEINT32_H */
735