• 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 maximum of two values.
92  * \param a	First input value.
93  * \param b Second input value.
94  * \return The largest of the two input values.
95  *//*--------------------------------------------------------------------*/
deMaxu32(deUint32 a,deUint32 b)96 DE_INLINE deUint32 deMaxu32 (deUint32 a, deUint32 b)
97 {
98 	return (a >= b) ? a : b;
99 }
100 
101 /*--------------------------------------------------------------------*//*!
102  * \brief Check if a value is in the <b>inclusive<b> range [mn, mx].
103  * \param a		Value to check for range.
104  * \param mn	Range minimum value.
105  * \param mx	Range maximum value.
106  * \return True if (a >= mn) and (a <= mx), false otherwise.
107  *
108  * \see deInBounds32()
109  *//*--------------------------------------------------------------------*/
deInRange32(int a,int mn,int mx)110 DE_INLINE deBool deInRange32 (int a, int mn, int mx)
111 {
112 	return (a >= mn) && (a <= mx);
113 }
114 
115 /*--------------------------------------------------------------------*//*!
116  * \brief Check if a value is in the half-inclusive bounds [mn, mx[.
117  * \param a		Value to check for range.
118  * \param mn	Range minimum value.
119  * \param mx	Range maximum value.
120  * \return True if (a >= mn) and (a < mx), false otherwise.
121  *
122  * \see deInRange32()
123  *//*--------------------------------------------------------------------*/
deInBounds32(int a,int mn,int mx)124 DE_INLINE deBool deInBounds32 (int a, int mn, int mx)
125 {
126 	return (a >= mn) && (a < mx);
127 }
128 
129 /*--------------------------------------------------------------------*//*!
130  * \brief Clamp a value into the range [mn, mx].
131  * \param a		Value to clamp.
132  * \param mn	Minimum value.
133  * \param mx	Maximum value.
134  * \return The clamped value in [mn, mx] range.
135  *//*--------------------------------------------------------------------*/
deClamp32(int a,int mn,int mx)136 DE_INLINE int deClamp32 (int a, int mn, int mx)
137 {
138 	DE_ASSERT(mn <= mx);
139 	if (a < mn) return mn;
140 	if (a > mx) return mx;
141 	return a;
142 }
143 
144 /*--------------------------------------------------------------------*//*!
145  * \brief Get the sign of an integer.
146  * \param a	Input value.
147  * \return +1 if a>0, 0 if a==0, -1 if a<0.
148  *//*--------------------------------------------------------------------*/
deSign32(int a)149 DE_INLINE int deSign32 (int a)
150 {
151 	if (a > 0) return +1;
152 	if (a < 0) return -1;
153 	return 0;
154 }
155 
156 /*--------------------------------------------------------------------*//*!
157  * \brief Extract the sign bit of a.
158  * \param a	Input value.
159  * \return 0x80000000 if a<0, 0 otherwise.
160  *//*--------------------------------------------------------------------*/
deSignBit32(deInt32 a)161 DE_INLINE deInt32 deSignBit32 (deInt32 a)
162 {
163 	return (deInt32)((deUint32)a & 0x80000000u);
164 }
165 
166 /*--------------------------------------------------------------------*//*!
167  * \brief Integer rotate right.
168  * \param val	Value to rotate.
169  * \param r		Number of bits to rotate (in range [0, 32]).
170  * \return The rotated value.
171  *//*--------------------------------------------------------------------*/
deRor32(int val,int r)172 DE_INLINE int deRor32 (int val, int r)
173 {
174 	DE_ASSERT(r >= 0 && r <= 32);
175 	if (r == 0 || r == 32)
176 		return val;
177 	else
178 		return (int)(((deUint32)val >> r) | ((deUint32)val << (32-r)));
179 }
180 
181 /*--------------------------------------------------------------------*//*!
182  * \brief Integer rotate left.
183  * \param val	Value to rotate.
184  * \param r		Number of bits to rotate (in range [0, 32]).
185  * \return The rotated value.
186  *//*--------------------------------------------------------------------*/
deRol32(int val,int r)187 DE_INLINE int deRol32 (int val, int r)
188 {
189 	DE_ASSERT(r >= 0 && r <= 32);
190 	if (r == 0 || r == 32)
191 		return val;
192 	else
193 		return (int)(((deUint32)val << r) | ((deUint32)val >> (32-r)));
194 }
195 
196 /*--------------------------------------------------------------------*//*!
197  * \brief Check if a value is a power-of-two.
198  * \param a Input value.
199  * \return True if input is a power-of-two value, false otherwise.
200  *
201  * \note Also returns true for zero.
202  *//*--------------------------------------------------------------------*/
deIsPowerOfTwo32(int a)203 DE_INLINE deBool deIsPowerOfTwo32 (int a)
204 {
205 	return ((a & (a - 1)) == 0);
206 }
207 
208 /*--------------------------------------------------------------------*//*!
209  * \brief Check if a value is a power-of-two.
210  * \param a Input value.
211  * \return True if input is a power-of-two value, false otherwise.
212  *
213  * \note Also returns true for zero.
214  *//*--------------------------------------------------------------------*/
deIsPowerOfTwo64(deUint64 a)215 DE_INLINE deBool deIsPowerOfTwo64 (deUint64 a)
216 {
217 	return ((a & (a - 1ull)) == 0);
218 }
219 
220 /*--------------------------------------------------------------------*//*!
221  * \brief Check if a value is a power-of-two.
222  * \param a Input value.
223  * \return True if input is a power-of-two value, false otherwise.
224  *
225  * \note Also returns true for zero.
226  *//*--------------------------------------------------------------------*/
deIsPowerOfTwoSize(size_t a)227 DE_INLINE deBool deIsPowerOfTwoSize (size_t a)
228 {
229 #if (DE_PTR_SIZE == 4)
230 	return deIsPowerOfTwo32(a);
231 #elif (DE_PTR_SIZE == 8)
232 	return deIsPowerOfTwo64(a);
233 #else
234 #	error "Invalid DE_PTR_SIZE"
235 #endif
236 }
237 
238 /*--------------------------------------------------------------------*//*!
239  * \brief Check if an integer is aligned to given power-of-two size.
240  * \param a		Input value.
241  * \param align	Alignment to check for.
242  * \return True if input is aligned, false otherwise.
243  *//*--------------------------------------------------------------------*/
deIsAligned32(int a,int align)244 DE_INLINE deBool deIsAligned32 (int a, int align)
245 {
246 	DE_ASSERT(deIsPowerOfTwo32(align));
247 	return ((a & (align-1)) == 0);
248 }
249 
250 /*--------------------------------------------------------------------*//*!
251  * \brief Check if a pointer is aligned to given power-of-two size.
252  * \param ptr	Input pointer.
253  * \param align	Alignment to check for (power-of-two).
254  * \return True if input is aligned, false otherwise.
255  *//*--------------------------------------------------------------------*/
deIsAlignedPtr(const void * ptr,deUintptr align)256 DE_INLINE deBool deIsAlignedPtr (const void* ptr, deUintptr align)
257 {
258 	DE_ASSERT((align & (align-1)) == 0); /* power of two */
259 	return (((deUintptr)ptr & (align-1)) == 0);
260 }
261 
262 /*--------------------------------------------------------------------*//*!
263  * \brief Align an integer to given power-of-two size.
264  * \param val	Input to align.
265  * \param align	Alignment to check for (power-of-two).
266  * \return The aligned value (larger or equal to input).
267  *//*--------------------------------------------------------------------*/
deAlign32(deInt32 val,deInt32 align)268 DE_INLINE deInt32 deAlign32 (deInt32 val, deInt32 align)
269 {
270 	DE_ASSERT(deIsPowerOfTwo32(align));
271 	return (val + align - 1) & ~(align - 1);
272 }
273 
274 /*--------------------------------------------------------------------*//*!
275  * \brief Align a pointer to given power-of-two size.
276  * \param ptr	Input pointer to align.
277  * \param align	Alignment to check for (power-of-two).
278  * \return The aligned pointer (larger or equal to input).
279  *//*--------------------------------------------------------------------*/
deAlignPtr(void * ptr,deUintptr align)280 DE_INLINE void* deAlignPtr (void* ptr, deUintptr align)
281 {
282 	deUintptr val = (deUintptr)ptr;
283 	DE_ASSERT((align & (align-1)) == 0); /* power of two */
284 	return (void*)((val + align - 1) & ~(align - 1));
285 }
286 
287 /*--------------------------------------------------------------------*//*!
288  * \brief Align a size_t value to given power-of-two size.
289  * \param ptr	Input value to align.
290  * \param align	Alignment to check for (power-of-two).
291  * \return The aligned size (larger or equal to input).
292  *//*--------------------------------------------------------------------*/
deAlignSize(size_t val,size_t align)293 DE_INLINE size_t deAlignSize (size_t val, size_t align)
294 {
295 	DE_ASSERT(deIsPowerOfTwoSize(align));
296 	return (val + align - 1) & ~(align - 1);
297 }
298 
299 extern const deInt8 g_clzLUT[256];
300 
301 /*--------------------------------------------------------------------*//*!
302  * \brief Compute number of leading zeros in an integer.
303  * \param a	Input value.
304  * \return The number of leading zero bits in the input.
305  *//*--------------------------------------------------------------------*/
deClz32(deUint32 a)306 DE_INLINE int deClz32 (deUint32 a)
307 {
308 #if (DE_COMPILER == DE_COMPILER_MSC)
309 	unsigned long i;
310 	if (_BitScanReverse(&i, (unsigned long)a) == 0)
311 		return 32;
312 	else
313 		return 31-i;
314 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
315 	if (a == 0)
316 		return 32;
317 	else
318 		return __builtin_clz((unsigned int)a);
319 #else
320 	if ((a & 0xFF000000u) != 0)
321 		return (int)g_clzLUT[a >> 24];
322 	if ((a & 0x00FF0000u) != 0)
323 		return 8 + (int)g_clzLUT[a >> 16];
324 	if ((a & 0x0000FF00u) != 0)
325 		return 16 + (int)g_clzLUT[a >> 8];
326 	return 24 + (int)g_clzLUT[a];
327 #endif
328 }
329 
330 extern const deInt8 g_ctzLUT[256];
331 
332 /*--------------------------------------------------------------------*//*!
333  * \brief Compute number of trailing zeros in an integer.
334  * \param a	Input value.
335  * \return The number of trailing zero bits in the input.
336  *//*--------------------------------------------------------------------*/
deCtz32(deUint32 a)337 DE_INLINE int deCtz32 (deUint32 a)
338 {
339 #if (DE_COMPILER == DE_COMPILER_MSC)
340 	unsigned long i;
341 	if (_BitScanForward(&i, (unsigned long)a) == 0)
342 		return 32;
343 	else
344 		return i;
345 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
346 	if (a == 0)
347 		return 32;
348 	else
349 		return __builtin_ctz((unsigned int)a);
350 #else
351 	if ((a & 0x00FFFFFFu) == 0)
352 		return (int)g_ctzLUT[a >> 24] + 24;
353 	if ((a & 0x0000FFFFu) == 0)
354 		return (int)g_ctzLUT[(a >> 16) & 0xffu] + 16;
355 	if ((a & 0x000000FFu) == 0)
356 		return (int)g_ctzLUT[(a >> 8) & 0xffu] + 8;
357 	return (int)g_ctzLUT[a & 0xffu];
358 #endif
359 }
360 
361 /*--------------------------------------------------------------------*//*!
362  * \brief Compute integer 'floor' of 'log2' for a positive integer.
363  * \param a	Input value.
364  * \return floor(log2(a)).
365  *//*--------------------------------------------------------------------*/
deLog2Floor32(deInt32 a)366 DE_INLINE int deLog2Floor32 (deInt32 a)
367 {
368 	DE_ASSERT(a > 0);
369 	return 31 - deClz32((deUint32)a);
370 }
371 
372 /*--------------------------------------------------------------------*//*!
373  * \brief Compute integer 'ceil' of 'log2' for a positive integer.
374  * \param a	Input value.
375  * \return ceil(log2(a)).
376  *//*--------------------------------------------------------------------*/
deLog2Ceil32(deInt32 a)377 DE_INLINE int deLog2Ceil32 (deInt32 a)
378 {
379 	int log2floor = deLog2Floor32(a);
380 	if (deIsPowerOfTwo32(a))
381 		return log2floor;
382 	else
383 		return log2floor+1;
384 }
385 
386 /* \todo [2012-04-28 pyry] Badly named, deprecated variant of deLog2Ceil32(). Remove once code has been fixed. */
deLog2Clz(deInt32 a)387 DE_INLINE deUint32 deLog2Clz(deInt32 a)
388 {
389 	return (deUint32)deLog2Ceil32(a);
390 }
391 
392 /*--------------------------------------------------------------------*//*!
393  * \brief Compute the bit population count of an integer.
394  * \param a	Input value.
395  * \return The number of one bits in the input.
396  *//*--------------------------------------------------------------------*/
dePop32(deUint32 a)397 DE_INLINE int dePop32 (deUint32 a)
398 {
399 	deUint32 mask0 = 0x55555555; /* 1-bit values. */
400 	deUint32 mask1 = 0x33333333; /* 2-bit values. */
401 	deUint32 mask2 = 0x0f0f0f0f; /* 4-bit values. */
402 	deUint32 mask3 = 0x00ff00ff; /* 8-bit values. */
403 	deUint32 mask4 = 0x0000ffff; /* 16-bit values. */
404 	deUint32 t = (deUint32)a;
405 	t = (t & mask0) + ((t>>1) & mask0);
406 	t = (t & mask1) + ((t>>2) & mask1);
407 	t = (t & mask2) + ((t>>4) & mask2);
408 	t = (t & mask3) + ((t>>8) & mask3);
409 	t = (t & mask4) + (t>>16);
410 	return (int)t;
411 }
412 
dePop64(deUint64 a)413 DE_INLINE int dePop64 (deUint64 a)
414 {
415 	return dePop32((deUint32)(a & 0xffffffffull)) + dePop32((deUint32)(a >> 32));
416 }
417 
418 /*--------------------------------------------------------------------*//*!
419  * \brief Reverse bytes in 32-bit integer (for example MSB -> LSB).
420  * \param a	Input value.
421  * \return The input with bytes reversed
422  *//*--------------------------------------------------------------------*/
deReverseBytes32(deUint32 v)423 DE_INLINE deUint32 deReverseBytes32 (deUint32 v)
424 {
425 	deUint32 b0 = v << 24;
426 	deUint32 b1 = (v & 0x0000ff00) << 8;
427 	deUint32 b2 = (v & 0x00ff0000) >> 8;
428 	deUint32 b3 = v >> 24;
429 	return b0|b1|b2|b3;
430 }
431 
432 /*--------------------------------------------------------------------*//*!
433  * \brief Reverse bytes in 16-bit integer (for example MSB -> LSB).
434  * \param a	Input value.
435  * \return The input with bytes reversed
436  *//*--------------------------------------------------------------------*/
deReverseBytes16(deUint16 v)437 DE_INLINE deUint16 deReverseBytes16 (deUint16 v)
438 {
439 	return (deUint16)((v << 8) | (v >> 8));
440 }
441 
deSafeMul32(deInt32 a,deInt32 b)442 DE_INLINE deInt32 deSafeMul32 (deInt32 a, deInt32 b)
443 {
444 	deInt32 res = a * b;
445 	DE_ASSERT((deInt64)res == ((deInt64)a * (deInt64)b));
446 	return res;
447 }
448 
deSafeAdd32(deInt32 a,deInt32 b)449 DE_INLINE deInt32 deSafeAdd32 (deInt32 a, deInt32 b)
450 {
451 	DE_ASSERT((deInt64)a + (deInt64)b == (deInt64)(a + b));
452 	return (a + b);
453 }
454 
deDivRoundUp32(deInt32 a,deInt32 b)455 DE_INLINE deInt32 deDivRoundUp32 (deInt32 a, deInt32 b)
456 {
457 	return a/b + ((a%b) ? 1 : 0);
458 }
459 
460 /* \todo [petri] Move to deInt64.h? */
461 
deMulAsr32(deInt32 a,deInt32 b,int shift)462 DE_INLINE deInt32 deMulAsr32 (deInt32 a, deInt32 b, int shift)
463 {
464 	return (deInt32)(((deInt64)a * (deInt64)b) >> shift);
465 }
466 
deSafeMulAsr32(deInt32 a,deInt32 b,int shift)467 DE_INLINE deInt32 deSafeMulAsr32 (deInt32 a, deInt32 b, int shift)
468 {
469 	deInt64 res = ((deInt64)a * (deInt64)b) >> shift;
470 	DE_ASSERT(res == (deInt64)(deInt32)res);
471 	return (deInt32)res;
472 }
473 
deSafeMuluAsr32(deUint32 a,deUint32 b,int shift)474 DE_INLINE deUint32 deSafeMuluAsr32 (deUint32 a, deUint32 b, int shift)
475 {
476 	deUint64 res = ((deUint64)a * (deUint64)b) >> shift;
477 	DE_ASSERT(res == (deUint64)(deUint32)res);
478 	return (deUint32)res;
479 }
480 
deMul32_32_64(deInt32 a,deInt32 b)481 DE_INLINE deInt64 deMul32_32_64 (deInt32 a, deInt32 b)
482 {
483 	return ((deInt64)a * (deInt64)b);
484 }
485 
deAbs64(deInt64 a)486 DE_INLINE deInt64 deAbs64 (deInt64 a)
487 {
488 	DE_ASSERT((deUint64) a != 0x8000000000000000LL);
489 	return (a >= 0) ? a : -a;
490 }
491 
deClz64(deUint64 a)492 DE_INLINE int deClz64 (deUint64 a)
493 {
494 	if ((a >> 32) != 0)
495 		return deClz32((deUint32)(a >> 32));
496 	return deClz32((deUint32)a) + 32;
497 }
498 
499 /* Common hash & compare functions. */
500 
deInt32Hash(deInt32 a)501 DE_INLINE deUint32 deInt32Hash (deInt32 a)
502 {
503 	/* From: http://www.concentric.net/~Ttwang/tech/inthash.htm */
504 	deUint32 key = (deUint32)a;
505 	key = (key ^ 61) ^ (key >> 16);
506 	key = key + (key << 3);
507 	key = key ^ (key >> 4);
508 	key = key * 0x27d4eb2d; /* prime/odd constant */
509 	key = key ^ (key >> 15);
510 	return key;
511 }
512 
deInt64Hash(deInt64 a)513 DE_INLINE deUint32 deInt64Hash (deInt64 a)
514 {
515 	/* From: http://www.concentric.net/~Ttwang/tech/inthash.htm */
516 	deUint64 key = (deUint64)a;
517 	key = (~key) + (key << 21); /* key = (key << 21) - key - 1; */
518 	key = key ^ (key >> 24);
519 	key = (key + (key << 3)) + (key << 8); /* key * 265 */
520 	key = key ^ (key >> 14);
521 	key = (key + (key << 2)) + (key << 4); /* key * 21 */
522 	key = key ^ (key >> 28);
523 	key = key + (key << 31);
524 	return (deUint32)key;
525 }
526 
deInt16Hash(deInt16 v)527 DE_INLINE deUint32	deInt16Hash		(deInt16 v)					{ return deInt32Hash(v);			}
deUint16Hash(deUint16 v)528 DE_INLINE deUint32	deUint16Hash	(deUint16 v)				{ return deInt32Hash((deInt32)v);	}
deUint32Hash(deUint32 v)529 DE_INLINE deUint32	deUint32Hash	(deUint32 v)				{ return deInt32Hash((deInt32)v);	}
deUint64Hash(deUint64 v)530 DE_INLINE deUint32	deUint64Hash	(deUint64 v)				{ return deInt64Hash((deInt64)v);	}
531 
deInt16Equal(deInt16 a,deInt16 b)532 DE_INLINE deBool	deInt16Equal	(deInt16 a, deInt16 b)		{ return (a == b);	}
deUint16Equal(deUint16 a,deUint16 b)533 DE_INLINE deBool	deUint16Equal	(deUint16 a, deUint16 b)	{ return (a == b);	}
deInt32Equal(deInt32 a,deInt32 b)534 DE_INLINE deBool	deInt32Equal	(deInt32 a, deInt32 b)		{ return (a == b);	}
deUint32Equal(deUint32 a,deUint32 b)535 DE_INLINE deBool	deUint32Equal	(deUint32 a, deUint32 b)	{ return (a == b);	}
deInt64Equal(deInt64 a,deInt64 b)536 DE_INLINE deBool	deInt64Equal	(deInt64 a, deInt64 b)		{ return (a == b);	}
deUint64Equal(deUint64 a,deUint64 b)537 DE_INLINE deBool	deUint64Equal	(deUint64 a, deUint64 b)	{ return (a == b);	}
538 
dePointerHash(const void * ptr)539 DE_INLINE deUint32	dePointerHash (const void* ptr)
540 {
541 	deUintptr val = (deUintptr)ptr;
542 #if (DE_PTR_SIZE == 4)
543 	return deInt32Hash((int)val);
544 #elif (DE_PTR_SIZE == 8)
545 	return deInt64Hash((deInt64)val);
546 #else
547 #	error Unsupported pointer size.
548 #endif
549 }
550 
dePointerEqual(const void * a,const void * b)551 DE_INLINE deBool dePointerEqual (const void* a, const void* b)
552 {
553 	return (a == b);
554 }
555 
556 /**
557  *	\brief	Modulo that generates the same sign as divisor and rounds toward
558  *			negative infinity -- assuming c99 %-operator.
559  */
deInt32ModF(deInt32 n,deInt32 d)560 DE_INLINE deInt32 deInt32ModF (deInt32 n, deInt32 d)
561 {
562 	deInt32 r = n%d;
563 	if ((r > 0 && d < 0) || (r < 0 && d > 0)) r = r+d;
564 	return r;
565 }
566 
deInt64InInt32Range(deInt64 x)567 DE_INLINE deBool deInt64InInt32Range (deInt64 x)
568 {
569 	return ((x >= (((deInt64)((deInt32)(-0x7FFFFFFF - 1))))) && (x <= ((1ll<<31)-1)));
570 }
571 
572 
deBitMask32(int leastSignificantBitNdx,int numBits)573 DE_INLINE deUint32 deBitMask32 (int leastSignificantBitNdx, int numBits)
574 {
575 	DE_ASSERT(deInRange32(leastSignificantBitNdx, 0, 32));
576 	DE_ASSERT(deInRange32(numBits, 0, 32));
577 	DE_ASSERT(deInRange32(leastSignificantBitNdx+numBits, 0, 32));
578 
579 	if (numBits < 32 && leastSignificantBitNdx < 32)
580 		return ((1u<<numBits)-1u) << (deUint32)leastSignificantBitNdx;
581 	else if (numBits == 0 && leastSignificantBitNdx == 32)
582 		return 0u;
583 	else
584 	{
585 		DE_ASSERT(numBits == 32 && leastSignificantBitNdx == 0);
586 		return 0xFFFFFFFFu;
587 	}
588 }
589 
deUintMaxValue32(int numBits)590 DE_INLINE deUint32 deUintMaxValue32 (int numBits)
591 {
592 	DE_ASSERT(deInRange32(numBits, 1, 32));
593 	if (numBits < 32)
594 		return ((1u<<numBits)-1u);
595 	else
596 		return 0xFFFFFFFFu;
597 }
598 
deIntMaxValue32(int numBits)599 DE_INLINE deInt32 deIntMaxValue32 (int numBits)
600 {
601 	DE_ASSERT(deInRange32(numBits, 1, 32));
602 	if (numBits < 32)
603 		return ((deInt32)1 << (numBits - 1)) - 1;
604 	else
605 	{
606 		/* avoid undefined behavior of int overflow when shifting */
607 		return 0x7FFFFFFF;
608 	}
609 }
610 
deIntMinValue32(int numBits)611 DE_INLINE deInt32 deIntMinValue32 (int numBits)
612 {
613 	DE_ASSERT(deInRange32(numBits, 1, 32));
614 	if (numBits < 32)
615 		return -((deInt32)1 << (numBits - 1));
616 	else
617 	{
618 		/* avoid undefined behavior of int overflow when shifting */
619 		return (deInt32)(-0x7FFFFFFF - 1);
620 	}
621 }
622 
deSignExtendTo32(deInt32 value,int numBits)623 DE_INLINE deInt32 deSignExtendTo32 (deInt32 value, int numBits)
624 {
625 	DE_ASSERT(deInRange32(numBits, 1, 32));
626 
627 	if (numBits < 32)
628 	{
629 		deBool		signSet		= ((deUint32)value & (1u<<(numBits-1))) != 0;
630 		deUint32	signMask	= deBitMask32(numBits, 32-numBits);
631 
632 		DE_ASSERT(((deUint32)value & signMask) == 0u);
633 
634 		return (deInt32)((deUint32)value | (signSet ? signMask : 0u));
635 	}
636 	else
637 		return value;
638 }
639 
640 DE_END_EXTERN_C
641 
642 #endif /* _DEINT32_H */
643