2 * IPRT - RTUINT32U methods for old 16-bit compilers (mainly for division).
6 * Copyright (C) 2011-2024 Oracle and/or its affiliates.
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
36 #ifndef IPRT_INCLUDED_uint32_h
37 #define IPRT_INCLUDED_uint32_h
38 #ifndef RT_WITHOUT_PRAGMA_ONCE
42 #include <iprt/cdefs.h>
43 #include <iprt/types.h>
48 /** @defgroup grp_rt_uint32 RTUInt32 - 32-bit Unsigned Integer Methods for 16-bit compilers.
53 #define RTUINT32_HAVE_32BIT_BASICS
57 * Test if a 32-bit unsigned integer value is zero.
59 * @returns true if they are, false if they aren't.
60 * @param pValue The input and output value.
62 DECLINLINE(bool) RTUInt32IsZero(PRTUINT32U pValue
)
64 return pValue
->s
.Lo
== 0
70 * Set a 32-bit unsigned integer value to zero.
73 * @param pResult The result variable.
75 DECLINLINE(PRTUINT32U
) RTUInt32SetZero(PRTUINT32U pResult
)
84 * Set a 32-bit unsigned integer value to the maximum value.
87 * @param pResult The result variable.
89 DECLINLINE(PRTUINT32U
) RTUInt32SetMax(PRTUINT32U pResult
)
91 pResult
->s
.Hi
= UINT16_MAX
;
92 pResult
->s
.Lo
= UINT16_MAX
;
100 * Adds two 32-bit unsigned integer values.
103 * @param pResult The result variable.
104 * @param pValue1 The first value.
105 * @param pValue2 The second value.
107 DECLINLINE(PRTUINT32U
) RTUInt32Add(PRTUINT32U pResult
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
109 #ifdef RTUINT32_HAVE_32BIT_BASICS
110 pResult
->u
= pValue1
->u
+ pValue2
->u
;
112 pResult
->s
.Hi
= pValue1
->s
.Hi
+ pValue2
->s
.Hi
;
113 pResult
->s
.Lo
= pValue1
->s
.Lo
+ pValue2
->s
.Lo
;
114 if (pResult
->s
.Lo
< pValue1
->s
.Lo
)
122 * Adds a 32-bit and a 16-bit unsigned integer values.
125 * @param pResult The result variable.
126 * @param pValue1 The first value.
127 * @param uValue2 The second value, 16-bit.
129 DECLINLINE(PRTUINT32U
) RTUInt32AddU16(PRTUINT32U pResult
, PCRTUINT32U pValue1
, uint16_t uValue2
)
131 #ifdef RTUINT32_HAVE_32BIT_BASICS
132 pResult
->u
= pValue1
->u
+ uValue2
;
134 pResult
->s
.Hi
= pValue1
->s
.Hi
;
135 pResult
->s
.Lo
= pValue1
->s
.Lo
+ uValue2
;
136 if (pResult
->s
.Lo
< pValue1
->s
.Lo
)
144 * Subtracts a 32-bit unsigned integer value from another.
147 * @param pResult The result variable.
148 * @param pValue1 The minuend value.
149 * @param pValue2 The subtrahend value.
151 DECLINLINE(PRTUINT32U
) RTUInt32Sub(PRTUINT32U pResult
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
153 #ifdef RTUINT32_HAVE_32BIT_BASICS
154 pResult
->u
= pValue1
->u
- pValue2
->u
;
156 pResult
->s
.Lo
= pValue1
->s
.Lo
- pValue2
->s
.Lo
;
157 pResult
->s
.Hi
= pValue1
->s
.Hi
- pValue2
->s
.Hi
;
158 if (pResult
->s
.Lo
> pValue1
->s
.Lo
)
166 * Multiplies two 32-bit unsigned integer values.
169 * @param pResult The result variable.
170 * @param pValue1 The first value.
171 * @param pValue2 The second value.
173 DECLINLINE(PRTUINT32U
) RTUInt32Mul(PRTUINT32U pResult
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
175 pResult
->u
= (uint32_t)pValue1
->s
.Lo
* pValue2
->s
.Lo
;
176 pResult
->s
.Hi
+= pValue1
->s
.Hi
* pValue2
->s
.Lo
;
177 pResult
->s
.Hi
+= pValue1
->s
.Lo
* pValue2
->s
.Hi
;
184 * Multiplies an 32-bit unsigned integer by a 16-bit unsigned integer value.
187 * @param pResult The result variable.
188 * @param pValue1 The first value.
189 * @param uValue2 The second value, 16-bit.
191 DECLINLINE(PRTUINT32U
) RTUInt32MulByU16(PRTUINT32U pResult
, PCRTUINT32U pValue1
, uint16_t uValue2
)
193 pResult
->u
= (uint32_t)pValue1
->s
.Lo
* uValue2
;
194 pResult
->s
.Hi
+= pValue1
->s
.Hi
* uValue2
;
199 DECLINLINE(PRTUINT32U
) RTUInt32DivRem(PRTUINT32U pQuotient
, PRTUINT32U pRemainder
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
);
202 * Divides a 32-bit unsigned integer value by another.
205 * @param pResult The result variable.
206 * @param pValue1 The dividend value.
207 * @param pValue2 The divisor value.
209 DECLINLINE(PRTUINT32U
) RTUInt32Div(PRTUINT32U pResult
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
212 return RTUInt32DivRem(pResult
, &Ignored
, pValue1
, pValue2
);
217 * Divides a 32-bit unsigned integer value by another, returning the remainder.
220 * @param pResult The result variable (remainder).
221 * @param pValue1 The dividend value.
222 * @param pValue2 The divisor value.
224 DECLINLINE(PRTUINT32U
) RTUInt32Mod(PRTUINT32U pResult
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
227 RTUInt32DivRem(&Ignored
, pResult
, pValue1
, pValue2
);
233 * Bitwise AND of two 32-bit unsigned integer values.
236 * @param pResult The result variable.
237 * @param pValue1 The first value.
238 * @param pValue2 The second value.
240 DECLINLINE(PRTUINT32U
) RTUInt32And(PRTUINT32U pResult
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
242 pResult
->s
.Hi
= pValue1
->s
.Hi
& pValue2
->s
.Hi
;
243 pResult
->s
.Lo
= pValue1
->s
.Lo
& pValue2
->s
.Lo
;
249 * Bitwise OR of two 32-bit unsigned integer values.
252 * @param pResult The result variable.
253 * @param pValue1 The first value.
254 * @param pValue2 The second value.
256 DECLINLINE(PRTUINT32U
) RTUInt32Or( PRTUINT32U pResult
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
258 pResult
->s
.Hi
= pValue1
->s
.Hi
| pValue2
->s
.Hi
;
259 pResult
->s
.Lo
= pValue1
->s
.Lo
| pValue2
->s
.Lo
;
265 * Bitwise XOR of two 32-bit unsigned integer values.
268 * @param pResult The result variable.
269 * @param pValue1 The first value.
270 * @param pValue2 The second value.
272 DECLINLINE(PRTUINT32U
) RTUInt32Xor(PRTUINT32U pResult
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
274 pResult
->s
.Hi
= pValue1
->s
.Hi
^ pValue2
->s
.Hi
;
275 pResult
->s
.Lo
= pValue1
->s
.Lo
^ pValue2
->s
.Lo
;
281 * Shifts a 32-bit unsigned integer value @a cBits to the left.
284 * @param pResult The result variable.
285 * @param pValue The value to shift.
286 * @param cBits The number of bits to shift it.
288 DECLINLINE(PRTUINT32U
) RTUInt32ShiftLeft(PRTUINT32U pResult
, PCRTUINT32U pValue
, int cBits
)
291 #ifdef RTUINT32_HAVE_32BIT_BASICS
292 pResult
->u
= pValue
->u
<< cBits
;
296 pResult
->s
.Lo
= pValue
->s
.Lo
<< cBits
;
297 pResult
->s
.Hi
= (pValue
->s
.Hi
<< cBits
) | (pValue
->s
.Lo
>> (16 - cBits
));
302 pResult
->s
.Hi
= pValue
->s
.Lo
<< (cBits
- 16);
310 * Shifts a 32-bit unsigned integer value @a cBits to the right.
313 * @param pResult The result variable.
314 * @param pValue The value to shift.
315 * @param cBits The number of bits to shift it.
317 DECLINLINE(PRTUINT32U
) RTUInt32ShiftRight(PRTUINT32U pResult
, PCRTUINT32U pValue
, int cBits
)
320 #ifdef RTUINT32_HAVE_32BIT_BASICS
321 pResult
->u
= pValue
->u
>> cBits
;
325 pResult
->s
.Hi
= pValue
->s
.Hi
>> cBits
;
326 pResult
->s
.Lo
= (pValue
->s
.Lo
>> cBits
) | (pValue
->s
.Hi
<< (16 - cBits
));
331 pResult
->s
.Lo
= pValue
->s
.Hi
>> (cBits
- 16);
339 * Boolean not (result 0 or 1).
342 * @param pResult The result variable.
343 * @param pValue The value.
345 DECLINLINE(PRTUINT32U
) RTUInt32BooleanNot(PRTUINT32U pResult
, PCRTUINT32U pValue
)
347 pResult
->s
.Lo
= pValue
->s
.Lo
|| pValue
->s
.Hi
? 0 : 1;
354 * Bitwise not (flips each bit of the 32 bits).
357 * @param pResult The result variable.
358 * @param pValue The value.
360 DECLINLINE(PRTUINT32U
) RTUInt32BitwiseNot(PRTUINT32U pResult
, PCRTUINT32U pValue
)
362 pResult
->s
.Hi
= ~pValue
->s
.Hi
;
363 pResult
->s
.Lo
= ~pValue
->s
.Lo
;
369 * Assigns one 32-bit unsigned integer value to another.
372 * @param pResult The result variable.
373 * @param pValue The value to assign.
375 DECLINLINE(PRTUINT32U
) RTUInt32Assign(PRTUINT32U pResult
, PCRTUINT32U pValue
)
377 pResult
->s
.Hi
= pValue
->s
.Hi
;
378 pResult
->s
.Lo
= pValue
->s
.Lo
;
384 * Assigns a boolean value to 32-bit unsigned integer.
386 * @returns pValueResult
387 * @param pValueResult The result variable.
388 * @param fValue The boolean value.
390 DECLINLINE(PRTUINT32U
) RTUInt32AssignBoolean(PRTUINT32U pValueResult
, bool fValue
)
392 pValueResult
->s
.Lo
= fValue
;
393 pValueResult
->s
.Hi
= 0;
399 * Assigns a 8-bit unsigned integer value to 32-bit unsigned integer.
401 * @returns pValueResult
402 * @param pValueResult The result variable.
403 * @param u8Value The 8-bit unsigned integer value.
405 DECLINLINE(PRTUINT32U
) RTUInt32AssignU8(PRTUINT32U pValueResult
, uint8_t u8Value
)
407 pValueResult
->s
.Lo
= u8Value
;
408 pValueResult
->s
.Hi
= 0;
414 * Assigns a 16-bit unsigned integer value to 32-bit unsigned integer.
416 * @returns pValueResult
417 * @param pValueResult The result variable.
418 * @param u16Value The 16-bit unsigned integer value.
420 DECLINLINE(PRTUINT32U
) RTUInt32AssignU16(PRTUINT32U pValueResult
, uint16_t u16Value
)
422 pValueResult
->s
.Lo
= u16Value
;
423 pValueResult
->s
.Hi
= 0;
429 * Adds two 32-bit unsigned integer values, storing the result in the first.
431 * @returns pValue1Result.
432 * @param pValue1Result The first value and result.
433 * @param pValue2 The second value.
435 DECLINLINE(PRTUINT32U
) RTUInt32AssignAdd(PRTUINT32U pValue1Result
, PCRTUINT32U pValue2
)
437 #ifdef RTUINT32_HAVE_32BIT_BASICS
438 pValue1Result
->u
+= pValue2
->u
;
440 uint16_t const uTmp
= pValue1Result
->s
.Lo
;
441 pValue1Result
->s
.Lo
+= pValue2
->s
.Lo
;
442 if (pValue1Result
->s
.Lo
< uTmp
)
443 pValue1Result
->s
.Hi
++;
444 pValue1Result
->s
.Hi
+= pValue2
->s
.Hi
;
446 return pValue1Result
;
451 * Subtracts two 32-bit unsigned integer values, storing the result in the
454 * @returns pValue1Result.
455 * @param pValue1Result The minuend value and result.
456 * @param pValue2 The subtrahend value.
458 DECLINLINE(PRTUINT32U
) RTUInt32AssignSub(PRTUINT32U pValue1Result
, PCRTUINT32U pValue2
)
460 #ifdef RTUINT32_HAVE_32BIT_BASICS
461 pValue1Result
->u
-= pValue2
->u
;
463 uint32_t const uTmp
= pValue1Result
->s
.Lo
;
464 pValue1Result
->s
.Lo
-= pValue2
->s
.Lo
;
465 if (pValue1Result
->s
.Lo
> uTmp
)
466 pValue1Result
->s
.Hi
--;
467 pValue1Result
->s
.Hi
-= pValue2
->s
.Hi
;
469 return pValue1Result
;
474 * Multiplies two 32-bit unsigned integer values, storing the result in the
477 * @returns pValue1Result.
478 * @param pValue1Result The first value and result.
479 * @param pValue2 The second value.
481 DECLINLINE(PRTUINT32U
) RTUInt32AssignMul(PRTUINT32U pValue1Result
, PCRTUINT32U pValue2
)
484 RTUInt32Mul(&Result
, pValue1Result
, pValue2
);
485 *pValue1Result
= Result
;
486 return pValue1Result
;
491 * Divides a 32-bit unsigned integer value by another, storing the result in
494 * @returns pValue1Result.
495 * @param pValue1Result The dividend value and result.
496 * @param pValue2 The divisor value.
498 DECLINLINE(PRTUINT32U
) RTUInt32AssignDiv(PRTUINT32U pValue1Result
, PCRTUINT32U pValue2
)
502 RTUInt32DivRem(&Result
, &Ignored
, pValue1Result
, pValue2
);
503 *pValue1Result
= Result
;
504 return pValue1Result
;
509 * Divides a 32-bit unsigned integer value by another, storing the remainder in
512 * @returns pValue1Result.
513 * @param pValue1Result The dividend value and result (remainder).
514 * @param pValue2 The divisor value.
516 DECLINLINE(PRTUINT32U
) RTUInt32AssignMod(PRTUINT32U pValue1Result
, PCRTUINT32U pValue2
)
520 RTUInt32DivRem(&Ignored
, &Result
, pValue1Result
, pValue2
);
521 *pValue1Result
= Result
;
522 return pValue1Result
;
527 * Performs a bitwise AND of two 32-bit unsigned integer values and assigned
528 * the result to the first one.
530 * @returns pValue1Result.
531 * @param pValue1Result The first value and result.
532 * @param pValue2 The second value.
534 DECLINLINE(PRTUINT32U
) RTUInt32AssignAnd(PRTUINT32U pValue1Result
, PCRTUINT32U pValue2
)
536 pValue1Result
->s
.Hi
&= pValue2
->s
.Hi
;
537 pValue1Result
->s
.Lo
&= pValue2
->s
.Lo
;
538 return pValue1Result
;
543 * Performs a bitwise AND of a 32-bit unsigned integer value and a mask made up
544 * of the first N bits, assigning the result to the the 32-bit value.
546 * @returns pValueResult.
547 * @param pValueResult The value and result.
548 * @param cBits The number of bits to AND (counting from the first
551 DECLINLINE(PRTUINT32U
) RTUInt32AssignAndNFirstBits(PRTUINT32U pValueResult
, unsigned cBits
)
553 #ifdef RTUINT32_HAVE_32BIT_BASICS
555 pValueResult
->u
&= RT_BIT_32(cBits
) - 1;
560 pValueResult
->s
.Lo
&= (UINT16_C(1) << cBits
) - 1;
561 pValueResult
->s
.Hi
= 0;
564 pValueResult
->s
.Hi
&= (UINT16_C(1) << (cBits
- 16)) - 1;
571 * Performs a bitwise OR of two 32-bit unsigned integer values and assigned
572 * the result to the first one.
574 * @returns pValue1Result.
575 * @param pValue1Result The first value and result.
576 * @param pValue2 The second value.
578 DECLINLINE(PRTUINT32U
) RTUInt32AssignOr(PRTUINT32U pValue1Result
, PCRTUINT32U pValue2
)
580 pValue1Result
->s
.Hi
|= pValue2
->s
.Hi
;
581 pValue1Result
->s
.Lo
|= pValue2
->s
.Lo
;
582 return pValue1Result
;
587 * ORs in a bit and assign the result to the input value.
589 * @returns pValue1Result.
590 * @param pValue1Result The first value and result.
591 * @param iBit The bit to set (0 based).
593 DECLINLINE(PRTUINT32U
) RTUInt32AssignOrBit(PRTUINT32U pValue1Result
, unsigned iBit
)
595 #ifdef RTUINT32_HAVE_32BIT_BASICS
596 pValue1Result
->u
|= RT_BIT_32(iBit
);
599 pValue1Result
->s
.Hi
|= UINT16_C(1) << (iBit
- 32);
601 pValue1Result
->s
.Lo
|= UINT16_C(1) << iBit
;
603 return pValue1Result
;
609 * Performs a bitwise XOR of two 32-bit unsigned integer values and assigned
610 * the result to the first one.
612 * @returns pValue1Result.
613 * @param pValue1Result The first value and result.
614 * @param pValue2 The second value.
616 DECLINLINE(PRTUINT32U
) RTUInt32AssignXor(PRTUINT32U pValue1Result
, PCRTUINT32U pValue2
)
618 pValue1Result
->s
.Hi
^= pValue2
->s
.Hi
;
619 pValue1Result
->s
.Lo
^= pValue2
->s
.Lo
;
620 return pValue1Result
;
625 * Performs a bitwise left shift on a 32-bit unsigned integer value, assigning
628 * @returns pValueResult.
629 * @param pValueResult The first value and result.
630 * @param cBits The number of bits to shift.
632 DECLINLINE(PRTUINT32U
) RTUInt32AssignShiftLeft(PRTUINT32U pValueResult
, int cBits
)
634 #ifndef RTUINT32_HAVE_32BIT_BASICS
635 RTUINT32U
const InVal
= *pValueResult
;
641 #ifdef RTUINT32_HAVE_32BIT_BASICS
642 pValueResult
->u
<<= cBits
;
646 pValueResult
->s
.Lo
= 0;
647 pValueResult
->s
.Hi
= InVal
.s
.Lo
<< (cBits
- 16);
651 pValueResult
->s
.Hi
= InVal
.s
.Hi
<< cBits
;
652 pValueResult
->s
.Hi
|= InVal
.s
.Lo
>> (16 - cBits
);
653 pValueResult
->s
.Lo
= InVal
.s
.Lo
<< cBits
;
662 #ifdef RTUINT32_HAVE_32BIT_BASICS
663 pValueResult
->u
>>= cBits
;
667 pValueResult
->s
.Hi
= 0;
668 pValueResult
->s
.Lo
= InVal
.s
.Hi
>> (cBits
- 16);
672 pValueResult
->s
.Lo
= InVal
.s
.Lo
>> cBits
;
673 pValueResult
->s
.Lo
|= InVal
.s
.Hi
<< (16 - cBits
);
674 pValueResult
->s
.Hi
= InVal
.s
.Hi
>> cBits
;
683 * Performs a bitwise left shift on a 32-bit unsigned integer value, assigning
686 * @returns pValueResult.
687 * @param pValueResult The first value and result.
688 * @param cBits The number of bits to shift.
690 DECLINLINE(PRTUINT32U
) RTUInt32AssignShiftRight(PRTUINT32U pValueResult
, int cBits
)
692 return RTUInt32AssignShiftLeft(pValueResult
, -cBits
);
697 * Performs a bitwise NOT on a 32-bit unsigned integer value, assigning the
700 * @returns pValueResult
701 * @param pValueResult The value and result.
703 DECLINLINE(PRTUINT32U
) RTUInt32AssignBitwiseNot(PRTUINT32U pValueResult
)
705 pValueResult
->s
.Hi
= ~pValueResult
->s
.Hi
;
706 pValueResult
->s
.Lo
= ~pValueResult
->s
.Lo
;
712 * Performs a boolean NOT on a 32-bit unsigned integer value, assigning the
715 * @returns pValueResult
716 * @param pValueResult The value and result.
718 DECLINLINE(PRTUINT32U
) RTUInt32AssignBooleanNot(PRTUINT32U pValueResult
)
720 return RTUInt32AssignBoolean(pValueResult
, RTUInt32IsZero(pValueResult
));
725 * Compares two 32-bit unsigned integer values.
727 * @retval 0 if equal.
728 * @retval -1 if the first value is smaller than the second.
729 * @retval 1 if the first value is larger than the second.
731 * @param pValue1 The first value.
732 * @param pValue2 The second value.
734 DECLINLINE(int) RTUInt32Compare(PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
736 if (pValue1
->s
.Hi
!= pValue2
->s
.Hi
)
737 return pValue1
->s
.Hi
> pValue2
->s
.Hi
? 1 : -1;
738 if (pValue1
->s
.Lo
!= pValue2
->s
.Lo
)
739 return pValue1
->s
.Lo
> pValue2
->s
.Lo
? 1 : -1;
745 * Tests if a 64-bit unsigned integer value is smaller than another.
747 * @returns true if the first value is smaller, false if not.
748 * @param pValue1 The first value.
749 * @param pValue2 The second value.
751 DECLINLINE(bool) RTUInt32IsSmaller(PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
753 #ifdef RTUINT32_HAVE_32BIT_BASICS
754 return pValue1
->u
< pValue2
->u
;
756 return pValue1
->s
.Hi
< pValue2
->s
.Hi
757 || ( pValue1
->s
.Hi
== pValue2
->s
.Hi
758 && pValue1
->s
.Lo
< pValue2
->s
.Lo
);
764 * Tests if a 32-bit unsigned integer value is larger than another.
766 * @returns true if the first value is larger, false if not.
767 * @param pValue1 The first value.
768 * @param pValue2 The second value.
770 DECLINLINE(bool) RTUInt32IsLarger(PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
772 #ifdef RTUINT32_HAVE_32BIT_BASICS
773 return pValue1
->u
> pValue2
->u
;
775 return pValue1
->s
.Hi
> pValue2
->s
.Hi
776 || ( pValue1
->s
.Hi
== pValue2
->s
.Hi
777 && pValue1
->s
.Lo
> pValue2
->s
.Lo
);
783 * Tests if a 64-bit unsigned integer value is larger or equal than another.
785 * @returns true if the first value is larger or equal, false if not.
786 * @param pValue1 The first value.
787 * @param pValue2 The second value.
789 DECLINLINE(bool) RTUInt32IsLargerOrEqual(PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
791 #ifdef RTUINT32_HAVE_32BIT_BASICS
792 return pValue1
->u
>= pValue2
->u
;
794 return pValue1
->s
.Hi
> pValue2
->s
.Hi
795 || ( pValue1
->s
.Hi
== pValue2
->s
.Hi
796 && pValue1
->s
.Lo
>= pValue2
->s
.Lo
);
802 * Tests if two 64-bit unsigned integer values not equal.
804 * @returns true if equal, false if not equal.
805 * @param pValue1 The first value.
806 * @param pValue2 The second value.
808 DECLINLINE(bool) RTUInt32IsEqual(PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
810 #ifdef RTUINT32_HAVE_32BIT_BASICS
811 return pValue1
->u
== pValue2
->u
;
813 return pValue1
->s
.Hi
== pValue2
->s
.Hi
814 && pValue1
->s
.Lo
== pValue2
->s
.Lo
;
820 * Tests if two 64-bit unsigned integer values are not equal.
822 * @returns true if not equal, false if equal.
823 * @param pValue1 The first value.
824 * @param pValue2 The second value.
826 DECLINLINE(bool) RTUInt32IsNotEqual(PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
828 return !RTUInt32IsEqual(pValue1
, pValue2
);
833 * Sets a bit in a 32-bit unsigned integer type.
835 * @returns pValueResult.
836 * @param pValueResult The input and output value.
837 * @param iBit The bit to set.
839 DECLINLINE(PRTUINT32U
) RTUInt32BitSet(PRTUINT32U pValueResult
, unsigned iBit
)
841 #ifdef RTUINT32_HAVE_32BIT_BASICS
843 pValueResult
->u
|= RT_BIT_32(iBit
);
846 pValueResult
->s
.Lo
|= UINT16_C(1) << iBit
;
848 pValueResult
->s
.Hi
|= UINT16_C(1) << (iBit
- 32);
855 * Sets a bit in a 32-bit unsigned integer type.
857 * @returns pValueResult.
858 * @param pValueResult The input and output value.
859 * @param iBit The bit to set.
861 DECLINLINE(PRTUINT32U
) RTUInt32BitClear(PRTUINT32U pValueResult
, unsigned iBit
)
863 #ifdef RTUINT32_HAVE_32BIT_BASICS
865 pValueResult
->u
&= ~RT_BIT_32(iBit
);
869 pValueResult
->s
.Lo
&= ~RT_BIT_32(iBit
);
871 pValueResult
->s
.Hi
&= ~RT_BIT_32(iBit
- 32);
878 * Tests if a bit in a 32-bit unsigned integer value is set.
880 * @returns pValueResult.
881 * @param pValueResult The input and output value.
882 * @param iBit The bit to test.
884 DECLINLINE(bool) RTUInt32BitTest(PRTUINT32U pValueResult
, unsigned iBit
)
887 #ifdef RTUINT32_HAVE_32BIT_BASICS
889 fRc
= RT_BOOL(pValueResult
->u
& RT_BIT_32(iBit
));
892 fRc
= RT_BOOL(pValueResult
->s
.Lo
& (UINT16_C(1) << iBit
));
894 fRc
= RT_BOOL(pValueResult
->s
.Hi
& (UINT16_C(1) << (iBit
- 64)));
903 * Set a range of bits a 32-bit unsigned integer value.
905 * @returns pValueResult.
906 * @param pValueResult The input and output value.
907 * @param iFirstBit The first bit to test.
908 * @param cBits The number of bits to set.
910 DECLINLINE(PRTUINT32U
) RTUInt32BitSetRange(PRTUINT32U pValueResult
, unsigned iFirstBit
, unsigned cBits
)
912 /* bounds check & fix. */
915 #ifdef RTUINT32_HAVE_32BIT_BASICS
916 if (iFirstBit
+ cBits
< 32)
917 pValueResult
->u
|= (RT_BIT_32(cBits
) - 1) << iFirstBit
;
919 pValueResult
->u
= UINT32_MAX
<< iFirstBit
;
921 if (iFirstBit
+ cBits
> 32)
922 cBits
= 32 - iFirstBit
;
923 if (iFirstBit
+ cBits
< 16)
924 pValueResult
->s
.Lo
|= ((UINT16_C(1) << cBits
) - 1) << iFirstBit
;
925 else if (iFirstBit
+ cBits
< 32 && iFirstBit
>= 16)
926 pValueResult
->s
.Hi
|= ((UINT16_C(1) << cBits
) - 1) << (iFirstBit
- 16);
929 RTUInt32BitSet(pValueResult
, iFirstBit
++);
937 * Test if all the bits of a 32-bit unsigned integer value are set.
939 * @returns true if they are, false if they aren't.
940 * @param pValue The input and output value.
942 DECLINLINE(bool) RTUInt32BitAreAllSet(PRTUINT32U pValue
)
944 return pValue
->s
.Hi
== UINT16_MAX
945 && pValue
->s
.Lo
== UINT16_MAX
;
950 * Test if all the bits of a 32-bit unsigned integer value are clear.
952 * @returns true if they are, false if they aren't.
953 * @param pValue The input and output value.
955 DECLINLINE(bool) RTUInt32BitAreAllClear(PRTUINT32U pValue
)
957 return RTUInt32IsZero(pValue
);
961 DECLINLINE(unsigned) RTUInt32BitCount(PCRTUINT32U pValue
)
964 if (pValue
->s
.Hi
!= 0)
965 cBits
= 16 + ASMBitLastSetU16(pValue
->s
.Hi
);
967 cBits
= ASMBitLastSetU16(pValue
->s
.Lo
);
973 * Divides a 32-bit unsigned integer value by another, returning both quotient
976 * @returns pQuotient, NULL if pValue2 is 0.
977 * @param pQuotient Where to return the quotient.
978 * @param pRemainder Where to return the remainder.
979 * @param pValue1 The dividend value.
980 * @param pValue2 The divisor value.
982 DECLINLINE(PRTUINT32U
) RTUInt32DivRem(PRTUINT32U pQuotient
, PRTUINT32U pRemainder
, PCRTUINT32U pValue1
, PCRTUINT32U pValue2
)
987 * Sort out all the special cases first.
989 /* Divide by zero or 1? */
995 if (pValue2
->s
.Lo
== 1)
997 RTUInt32SetZero(pRemainder
);
998 *pQuotient
= *pValue1
;
1001 /** @todo RTUInt32DivModByU32 */
1004 /* Dividend is smaller? */
1005 iDiff
= RTUInt32Compare(pValue1
, pValue2
);
1008 *pRemainder
= *pValue1
;
1009 RTUInt32SetZero(pQuotient
);
1012 /* The values are equal? */
1013 else if (iDiff
== 0)
1015 RTUInt32SetZero(pRemainder
);
1016 RTUInt32AssignU8(pQuotient
, 1);
1023 unsigned iBitAdder
= RTUInt32BitCount(pValue1
) - RTUInt32BitCount(pValue2
);
1024 RTUINT32U NormDivisor
= *pValue2
;
1027 RTUInt32ShiftLeft(&NormDivisor
, pValue2
, iBitAdder
);
1028 if (RTUInt32IsLarger(&NormDivisor
, pValue1
))
1030 RTUInt32AssignShiftRight(&NormDivisor
, 1);
1035 NormDivisor
= *pValue2
;
1037 RTUInt32SetZero(pQuotient
);
1038 *pRemainder
= *pValue1
;
1043 if (RTUInt32IsLargerOrEqual(pRemainder
, pValue2
))
1047 if (RTUInt32IsLargerOrEqual(pRemainder
, &NormDivisor
))
1049 RTUInt32AssignSub(pRemainder
, &NormDivisor
);
1050 RTUInt32AssignOrBit(pQuotient
, iBitAdder
);
1052 if (RTUInt32IsSmaller(pRemainder
, pValue2
))
1054 RTUInt32AssignShiftRight(&NormDivisor
, 1);
1067 #endif /* !IPRT_INCLUDED_uint32_h */