Add deInt64 alignment functions to delibs
[platform/upstream/VK-GL-CTS.git] / framework / delibs / debase / deInt32.h
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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  *//*--------------------------------------------------------------------*/
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 an integer is aligned to given power-of-two size.
252  * \param a             Input value.
253  * \param align Alignment to check for.
254  * \return True if input is aligned, false otherwise.
255  *//*--------------------------------------------------------------------*/
256 DE_INLINE deBool deIsAligned64 (deInt64 a, deInt64 align)
257 {
258         DE_ASSERT(deIsPowerOfTwo64(align));
259         return ((a & (align-1)) == 0);
260 }
261
262 /*--------------------------------------------------------------------*//*!
263  * \brief Check if a pointer is aligned to given power-of-two size.
264  * \param ptr   Input pointer.
265  * \param align Alignment to check for (power-of-two).
266  * \return True if input is aligned, false otherwise.
267  *//*--------------------------------------------------------------------*/
268 DE_INLINE deBool deIsAlignedPtr (const void* ptr, deUintptr align)
269 {
270         DE_ASSERT((align & (align-1)) == 0); /* power of two */
271         return (((deUintptr)ptr & (align-1)) == 0);
272 }
273
274 /*--------------------------------------------------------------------*//*!
275  * \brief Align an integer to given power-of-two size.
276  * \param val   Input to align.
277  * \param align Alignment to check for (power-of-two).
278  * \return The aligned value (larger or equal to input).
279  *//*--------------------------------------------------------------------*/
280 DE_INLINE deInt32 deAlign32 (deInt32 val, deInt32 align)
281 {
282         DE_ASSERT(deIsPowerOfTwo32(align));
283         return (val + align - 1) & ~(align - 1);
284 }
285
286 /*--------------------------------------------------------------------*//*!
287  * \brief Align an integer to given power-of-two size.
288  * \param val   Input to align.
289  * \param align Alignment to check for (power-of-two).
290  * \return The aligned value (larger or equal to input).
291  *//*--------------------------------------------------------------------*/
292 DE_INLINE deInt64 deAlign64 (deInt64 val, deInt64 align)
293 {
294         DE_ASSERT(deIsPowerOfTwo64(align));
295         return (val + align - 1) & ~(align - 1);
296 }
297
298 /*--------------------------------------------------------------------*//*!
299  * \brief Align a pointer to given power-of-two size.
300  * \param ptr   Input pointer to align.
301  * \param align Alignment to check for (power-of-two).
302  * \return The aligned pointer (larger or equal to input).
303  *//*--------------------------------------------------------------------*/
304 DE_INLINE void* deAlignPtr (void* ptr, deUintptr align)
305 {
306         deUintptr val = (deUintptr)ptr;
307         DE_ASSERT((align & (align-1)) == 0); /* power of two */
308         return (void*)((val + align - 1) & ~(align - 1));
309 }
310
311 /*--------------------------------------------------------------------*//*!
312  * \brief Align a size_t value to given power-of-two size.
313  * \param ptr   Input value to align.
314  * \param align Alignment to check for (power-of-two).
315  * \return The aligned size (larger or equal to input).
316  *//*--------------------------------------------------------------------*/
317 DE_INLINE size_t deAlignSize (size_t val, size_t align)
318 {
319         DE_ASSERT(deIsPowerOfTwoSize(align));
320         return (val + align - 1) & ~(align - 1);
321 }
322
323 extern const deInt8 g_clzLUT[256];
324
325 /*--------------------------------------------------------------------*//*!
326  * \brief Compute number of leading zeros in an integer.
327  * \param a     Input value.
328  * \return The number of leading zero bits in the input.
329  *//*--------------------------------------------------------------------*/
330 DE_INLINE int deClz32 (deUint32 a)
331 {
332 #if (DE_COMPILER == DE_COMPILER_MSC)
333         unsigned long i;
334         if (_BitScanReverse(&i, (unsigned long)a) == 0)
335                 return 32;
336         else
337                 return 31-i;
338 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
339         if (a == 0)
340                 return 32;
341         else
342                 return __builtin_clz((unsigned int)a);
343 #else
344         if ((a & 0xFF000000u) != 0)
345                 return (int)g_clzLUT[a >> 24];
346         if ((a & 0x00FF0000u) != 0)
347                 return 8 + (int)g_clzLUT[a >> 16];
348         if ((a & 0x0000FF00u) != 0)
349                 return 16 + (int)g_clzLUT[a >> 8];
350         return 24 + (int)g_clzLUT[a];
351 #endif
352 }
353
354 extern const deInt8 g_ctzLUT[256];
355
356 /*--------------------------------------------------------------------*//*!
357  * \brief Compute number of trailing zeros in an integer.
358  * \param a     Input value.
359  * \return The number of trailing zero bits in the input.
360  *//*--------------------------------------------------------------------*/
361 DE_INLINE int deCtz32 (deUint32 a)
362 {
363 #if (DE_COMPILER == DE_COMPILER_MSC)
364         unsigned long i;
365         if (_BitScanForward(&i, (unsigned long)a) == 0)
366                 return 32;
367         else
368                 return i;
369 #elif (DE_COMPILER == DE_COMPILER_GCC) || (DE_COMPILER == DE_COMPILER_CLANG)
370         if (a == 0)
371                 return 32;
372         else
373                 return __builtin_ctz((unsigned int)a);
374 #else
375         if ((a & 0x00FFFFFFu) == 0)
376                 return (int)g_ctzLUT[a >> 24] + 24;
377         if ((a & 0x0000FFFFu) == 0)
378                 return (int)g_ctzLUT[(a >> 16) & 0xffu] + 16;
379         if ((a & 0x000000FFu) == 0)
380                 return (int)g_ctzLUT[(a >> 8) & 0xffu] + 8;
381         return (int)g_ctzLUT[a & 0xffu];
382 #endif
383 }
384
385 /*--------------------------------------------------------------------*//*!
386  * \brief Compute integer 'floor' of 'log2' for a positive integer.
387  * \param a     Input value.
388  * \return floor(log2(a)).
389  *//*--------------------------------------------------------------------*/
390 DE_INLINE int deLog2Floor32 (deInt32 a)
391 {
392         DE_ASSERT(a > 0);
393         return 31 - deClz32((deUint32)a);
394 }
395
396 /*--------------------------------------------------------------------*//*!
397  * \brief Compute integer 'ceil' of 'log2' for a positive integer.
398  * \param a     Input value.
399  * \return ceil(log2(a)).
400  *//*--------------------------------------------------------------------*/
401 DE_INLINE int deLog2Ceil32 (deInt32 a)
402 {
403         int log2floor = deLog2Floor32(a);
404         if (deIsPowerOfTwo32(a))
405                 return log2floor;
406         else
407                 return log2floor+1;
408 }
409
410 /* \todo [2012-04-28 pyry] Badly named, deprecated variant of deLog2Ceil32(). Remove once code has been fixed. */
411 DE_INLINE deUint32 deLog2Clz(deInt32 a)
412 {
413         return (deUint32)deLog2Ceil32(a);
414 }
415
416 /*--------------------------------------------------------------------*//*!
417  * \brief Compute the bit population count of an integer.
418  * \param a     Input value.
419  * \return The number of one bits in the input.
420  *//*--------------------------------------------------------------------*/
421 DE_INLINE int dePop32 (deUint32 a)
422 {
423         deUint32 mask0 = 0x55555555; /* 1-bit values. */
424         deUint32 mask1 = 0x33333333; /* 2-bit values. */
425         deUint32 mask2 = 0x0f0f0f0f; /* 4-bit values. */
426         deUint32 mask3 = 0x00ff00ff; /* 8-bit values. */
427         deUint32 mask4 = 0x0000ffff; /* 16-bit values. */
428         deUint32 t = (deUint32)a;
429         t = (t & mask0) + ((t>>1) & mask0);
430         t = (t & mask1) + ((t>>2) & mask1);
431         t = (t & mask2) + ((t>>4) & mask2);
432         t = (t & mask3) + ((t>>8) & mask3);
433         t = (t & mask4) + (t>>16);
434         return (int)t;
435 }
436
437 DE_INLINE int dePop64 (deUint64 a)
438 {
439         return dePop32((deUint32)(a & 0xffffffffull)) + dePop32((deUint32)(a >> 32));
440 }
441
442 /*--------------------------------------------------------------------*//*!
443  * \brief Reverse bytes in 32-bit integer (for example MSB -> LSB).
444  * \param a     Input value.
445  * \return The input with bytes reversed
446  *//*--------------------------------------------------------------------*/
447 DE_INLINE deUint32 deReverseBytes32 (deUint32 v)
448 {
449         deUint32 b0 = v << 24;
450         deUint32 b1 = (v & 0x0000ff00) << 8;
451         deUint32 b2 = (v & 0x00ff0000) >> 8;
452         deUint32 b3 = v >> 24;
453         return b0|b1|b2|b3;
454 }
455
456 /*--------------------------------------------------------------------*//*!
457  * \brief Reverse bytes in 16-bit integer (for example MSB -> LSB).
458  * \param a     Input value.
459  * \return The input with bytes reversed
460  *//*--------------------------------------------------------------------*/
461 DE_INLINE deUint16 deReverseBytes16 (deUint16 v)
462 {
463         return (deUint16)((v << 8) | (v >> 8));
464 }
465
466 DE_INLINE deInt32 deSafeMul32 (deInt32 a, deInt32 b)
467 {
468         deInt32 res = a * b;
469         DE_ASSERT((deInt64)res == ((deInt64)a * (deInt64)b));
470         return res;
471 }
472
473 DE_INLINE deInt32 deSafeAdd32 (deInt32 a, deInt32 b)
474 {
475         DE_ASSERT((deInt64)a + (deInt64)b == (deInt64)(a + b));
476         return (a + b);
477 }
478
479 DE_INLINE deInt32 deDivRoundUp32 (deInt32 a, deInt32 b)
480 {
481         return a/b + ((a%b) ? 1 : 0);
482 }
483
484 /* \todo [petri] Move to deInt64.h? */
485
486 DE_INLINE deInt32 deMulAsr32 (deInt32 a, deInt32 b, int shift)
487 {
488         return (deInt32)(((deInt64)a * (deInt64)b) >> shift);
489 }
490
491 DE_INLINE deInt32 deSafeMulAsr32 (deInt32 a, deInt32 b, int shift)
492 {
493         deInt64 res = ((deInt64)a * (deInt64)b) >> shift;
494         DE_ASSERT(res == (deInt64)(deInt32)res);
495         return (deInt32)res;
496 }
497
498 DE_INLINE deUint32 deSafeMuluAsr32 (deUint32 a, deUint32 b, int shift)
499 {
500         deUint64 res = ((deUint64)a * (deUint64)b) >> shift;
501         DE_ASSERT(res == (deUint64)(deUint32)res);
502         return (deUint32)res;
503 }
504
505 DE_INLINE deInt64 deMul32_32_64 (deInt32 a, deInt32 b)
506 {
507         return ((deInt64)a * (deInt64)b);
508 }
509
510 DE_INLINE deInt64 deAbs64 (deInt64 a)
511 {
512         DE_ASSERT((deUint64) a != 0x8000000000000000LL);
513         return (a >= 0) ? a : -a;
514 }
515
516 DE_INLINE int deClz64 (deUint64 a)
517 {
518         if ((a >> 32) != 0)
519                 return deClz32((deUint32)(a >> 32));
520         return deClz32((deUint32)a) + 32;
521 }
522
523 /* Common hash & compare functions. */
524
525 DE_INLINE deUint32 deInt32Hash (deInt32 a)
526 {
527         /* From: http://www.concentric.net/~Ttwang/tech/inthash.htm */
528         deUint32 key = (deUint32)a;
529         key = (key ^ 61) ^ (key >> 16);
530         key = key + (key << 3);
531         key = key ^ (key >> 4);
532         key = key * 0x27d4eb2d; /* prime/odd constant */
533         key = key ^ (key >> 15);
534         return key;
535 }
536
537 DE_INLINE deUint32 deInt64Hash (deInt64 a)
538 {
539         /* From: http://www.concentric.net/~Ttwang/tech/inthash.htm */
540         deUint64 key = (deUint64)a;
541         key = (~key) + (key << 21); /* key = (key << 21) - key - 1; */
542         key = key ^ (key >> 24);
543         key = (key + (key << 3)) + (key << 8); /* key * 265 */
544         key = key ^ (key >> 14);
545         key = (key + (key << 2)) + (key << 4); /* key * 21 */
546         key = key ^ (key >> 28);
547         key = key + (key << 31);
548         return (deUint32)key;
549 }
550
551 DE_INLINE deUint32      deInt16Hash             (deInt16 v)                                     { return deInt32Hash(v);                        }
552 DE_INLINE deUint32      deUint16Hash    (deUint16 v)                            { return deInt32Hash((deInt32)v);       }
553 DE_INLINE deUint32      deUint32Hash    (deUint32 v)                            { return deInt32Hash((deInt32)v);       }
554 DE_INLINE deUint32      deUint64Hash    (deUint64 v)                            { return deInt64Hash((deInt64)v);       }
555
556 DE_INLINE deBool        deInt16Equal    (deInt16 a, deInt16 b)          { return (a == b);      }
557 DE_INLINE deBool        deUint16Equal   (deUint16 a, deUint16 b)        { return (a == b);      }
558 DE_INLINE deBool        deInt32Equal    (deInt32 a, deInt32 b)          { return (a == b);      }
559 DE_INLINE deBool        deUint32Equal   (deUint32 a, deUint32 b)        { return (a == b);      }
560 DE_INLINE deBool        deInt64Equal    (deInt64 a, deInt64 b)          { return (a == b);      }
561 DE_INLINE deBool        deUint64Equal   (deUint64 a, deUint64 b)        { return (a == b);      }
562
563 DE_INLINE deUint32      dePointerHash (const void* ptr)
564 {
565         deUintptr val = (deUintptr)ptr;
566 #if (DE_PTR_SIZE == 4)
567         return deInt32Hash((int)val);
568 #elif (DE_PTR_SIZE == 8)
569         return deInt64Hash((deInt64)val);
570 #else
571 #       error Unsupported pointer size.
572 #endif
573 }
574
575 DE_INLINE deBool dePointerEqual (const void* a, const void* b)
576 {
577         return (a == b);
578 }
579
580 /**
581  *      \brief  Modulo that generates the same sign as divisor and rounds toward
582  *                      negative infinity -- assuming c99 %-operator.
583  */
584 DE_INLINE deInt32 deInt32ModF (deInt32 n, deInt32 d)
585 {
586         deInt32 r = n%d;
587         if ((r > 0 && d < 0) || (r < 0 && d > 0)) r = r+d;
588         return r;
589 }
590
591 DE_INLINE deBool deInt64InInt32Range (deInt64 x)
592 {
593         return ((x >= (((deInt64)((deInt32)(-0x7FFFFFFF - 1))))) && (x <= ((1ll<<31)-1)));
594 }
595
596
597 DE_INLINE deUint32 deBitMask32 (int leastSignificantBitNdx, int numBits)
598 {
599         DE_ASSERT(deInRange32(leastSignificantBitNdx, 0, 32));
600         DE_ASSERT(deInRange32(numBits, 0, 32));
601         DE_ASSERT(deInRange32(leastSignificantBitNdx+numBits, 0, 32));
602
603         if (numBits < 32 && leastSignificantBitNdx < 32)
604                 return ((1u<<numBits)-1u) << (deUint32)leastSignificantBitNdx;
605         else if (numBits == 0 && leastSignificantBitNdx == 32)
606                 return 0u;
607         else
608         {
609                 DE_ASSERT(numBits == 32 && leastSignificantBitNdx == 0);
610                 return 0xFFFFFFFFu;
611         }
612 }
613
614 DE_INLINE deUint32 deUintMaxValue32 (int numBits)
615 {
616         DE_ASSERT(deInRange32(numBits, 1, 32));
617         if (numBits < 32)
618                 return ((1u<<numBits)-1u);
619         else
620                 return 0xFFFFFFFFu;
621 }
622
623 DE_INLINE deInt32 deIntMaxValue32 (int numBits)
624 {
625         DE_ASSERT(deInRange32(numBits, 1, 32));
626         if (numBits < 32)
627                 return ((deInt32)1 << (numBits - 1)) - 1;
628         else
629         {
630                 /* avoid undefined behavior of int overflow when shifting */
631                 return 0x7FFFFFFF;
632         }
633 }
634
635 DE_INLINE deInt32 deIntMinValue32 (int numBits)
636 {
637         DE_ASSERT(deInRange32(numBits, 1, 32));
638         if (numBits < 32)
639                 return -((deInt32)1 << (numBits - 1));
640         else
641         {
642                 /* avoid undefined behavior of int overflow when shifting */
643                 return (deInt32)(-0x7FFFFFFF - 1);
644         }
645 }
646
647 DE_INLINE deInt32 deSignExtendTo32 (deInt32 value, int numBits)
648 {
649         DE_ASSERT(deInRange32(numBits, 1, 32));
650
651         if (numBits < 32)
652         {
653                 deBool          signSet         = ((deUint32)value & (1u<<(numBits-1))) != 0;
654                 deUint32        signMask        = deBitMask32(numBits, 32-numBits);
655
656                 DE_ASSERT(((deUint32)value & signMask) == 0u);
657
658                 return (deInt32)((deUint32)value | (signSet ? signMask : 0u));
659         }
660         else
661                 return value;
662 }
663
664 DE_END_EXTERN_C
665
666 #endif /* _DEINT32_H */