GuestHost/installation/VBoxWinDrvInst.cpp: Try harder if DiInstallDriverW() returns...
[vbox.git] / include / iprt / uint64.h
blobdd6ca61536e3ca2ee6f1af5b18ffc20a0161ad04
1 /** @file
2 * IPRT - RTUINT64U methods for old 32-bit and 16-bit compilers.
3 */
5 /*
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
14 * License.
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_uint64_h
37 #define IPRT_INCLUDED_uint64_h
38 #ifndef RT_WITHOUT_PRAGMA_ONCE
39 # pragma once
40 #endif
42 #include <iprt/cdefs.h>
43 #include <iprt/types.h>
44 #include <iprt/asm.h>
46 RT_C_DECLS_BEGIN
48 /** @defgroup grp_rt_uint64 RTUInt64 - 64-bit Unsigned Integer Methods for ancient compilers
49 * @ingroup grp_rt
50 * @{
54 /**
55 * Test if a 128-bit unsigned integer value is zero.
57 * @returns true if they are, false if they aren't.
58 * @param pValue The value to examine.
60 DECLINLINE(bool) RTUInt64IsZero(PCRTUINT64U pValue)
62 #if ARCH_BITS >= 32
63 return pValue->s.Lo == 0
64 && pValue->s.Hi == 0;
65 #else
66 return pValue->Words.w0 == 0
67 && pValue->Words.w1 == 0
68 && pValue->Words.w2 == 0
69 && pValue->Words.w3 == 0;
70 #endif
74 /**
75 * Checks if the sign-bit is set.
77 * @returns Sign bit.
78 * @param pValue The value to examine.
80 DECLINLINE(bool) RTUInt64IsSigned(PCRTUINT64U pValue)
82 #if ARCH_BITS >= 32
83 return RT_BOOL(pValue->DWords.dw1 & RT_BIT_32(31));
84 #else
85 return RT_BOOL(pValue->Words.w3 & ((uint16_t)1 << 15));
86 #endif
90 /**
91 * Set a 128-bit unsigned integer value to zero.
93 * @returns pResult
94 * @param pResult The result variable.
96 DECLINLINE(PRTUINT64U) RTUInt64SetZero(PRTUINT64U pResult)
98 #if ARCH_BITS >= 32
99 pResult->s.Hi = 0;
100 pResult->s.Lo = 0;
101 #else
102 pResult->Words.w0 = 0;
103 pResult->Words.w1 = 0;
104 pResult->Words.w2 = 0;
105 pResult->Words.w3 = 0;
106 #endif
107 return pResult;
112 * Set a 32-bit unsigned integer value to the maximum value.
114 * @returns pResult
115 * @param pResult The result variable.
117 DECLINLINE(PRTUINT64U) RTUInt64SetMax(PRTUINT64U pResult)
119 #if ARCH_BITS >= 32
120 pResult->s.Hi = UINT32_MAX;
121 pResult->s.Lo = UINT32_MAX;
122 #else
123 pResult->Words.w0 = UINT16_MAX;
124 pResult->Words.w1 = UINT16_MAX;
125 pResult->Words.w2 = UINT16_MAX;
126 pResult->Words.w3 = UINT16_MAX;
127 #endif
128 return pResult;
135 * Adds two 64-bit unsigned integer values.
137 * @returns pResult
138 * @param pResult The result variable.
139 * @param pValue1 The first value.
140 * @param pValue2 The second value.
142 DECLINLINE(PRTUINT64U) RTUInt64Add(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
144 pResult->s.Hi = pValue1->s.Hi + pValue2->s.Hi;
145 pResult->s.Lo = pValue1->s.Lo + pValue2->s.Lo;
146 if (pResult->s.Lo < pValue1->s.Lo)
147 pResult->s.Hi++;
148 return pResult;
153 * Adds a 64-bit and a 32-bit unsigned integer values.
155 * @returns pResult
156 * @param pResult The result variable.
157 * @param pValue1 The first value.
158 * @param uValue2 The second value, 32-bit.
160 DECLINLINE(PRTUINT64U) RTUInt64AddU32(PRTUINT64U pResult, PCRTUINT64U pValue1, uint32_t uValue2)
162 pResult->s.Hi = pValue1->s.Hi;
163 pResult->s.Lo = pValue1->s.Lo + uValue2;
164 if (pResult->s.Lo < pValue1->s.Lo)
165 pResult->s.Hi++;
166 return pResult;
171 * Subtracts a 64-bit unsigned integer value from another.
173 * @returns pResult
174 * @param pResult The result variable.
175 * @param pValue1 The minuend value.
176 * @param pValue2 The subtrahend value.
178 DECLINLINE(PRTUINT64U) RTUInt64Sub(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
180 pResult->s.Lo = pValue1->s.Lo - pValue2->s.Lo;
181 pResult->s.Hi = pValue1->s.Hi - pValue2->s.Hi;
182 if (pResult->s.Lo > pValue1->s.Lo)
183 pResult->s.Hi--;
184 return pResult;
189 * Calculates the negated number (special case of subtraction)
191 * @returns pResult
192 * @param pResult The result variable.
193 * @param pValue The value to negate.
195 DECLINLINE(PRTUINT64U) RTUInt64Neg(PRTUINT64U pResult, PCRTUINT64U pValue)
197 pResult->s.Lo = UINT32_C(0) - pValue->s.Lo;
198 pResult->s.Hi = UINT32_C(0) - pValue->s.Hi;
199 if (pResult->s.Lo > UINT32_C(0))
200 pResult->s.Hi--;
201 return pResult;
206 * Multiplies two 64-bit unsigned integer values.
208 * @returns pResult
209 * @param pResult The result variable.
210 * @param pValue1 The first value.
211 * @param pValue2 The second value.
213 DECLINLINE(PRTUINT64U) RTUInt64Mul(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
215 RTUINT32U uTmp;
217 /* multiply all words in v1 by v2.w0. */
218 pResult->s.Lo = (uint32_t)pValue1->Words.w0 * pValue2->Words.w0;
220 uTmp.u = (uint32_t)pValue1->Words.w1 * pValue2->Words.w0;
221 pResult->Words.w3 = 0;
222 pResult->Words.w2 = uTmp.Words.w1;
223 pResult->Words.w1 += uTmp.Words.w0;
224 if (pResult->Words.w1 < uTmp.Words.w0)
225 if (pResult->Words.w2++ == UINT16_MAX)
226 pResult->Words.w3++;
228 pResult->s.Hi += (uint32_t)pValue1->Words.w2 * pValue2->Words.w0;
229 pResult->Words.w3 += pValue1->Words.w3 * pValue2->Words.w0;
231 /* multiply w0, w1 & w2 in v1 by v2.w1. */
232 uTmp.u = (uint32_t)pValue1->Words.w0 * pValue2->Words.w1;
233 pResult->Words.w1 += uTmp.Words.w0;
234 if (pResult->Words.w1 < uTmp.Words.w0)
235 if (pResult->Words.w2++ == UINT16_MAX)
236 pResult->Words.w3++;
238 pResult->Words.w2 += uTmp.Words.w1;
239 if (pResult->Words.w2 < uTmp.Words.w1)
240 pResult->Words.w3++;
242 pResult->s.Hi += (uint32_t)pValue1->Words.w1 * pValue2->Words.w1;
243 pResult->Words.w3 += pValue1->Words.w2 * pValue2->Words.w1;
245 /* multiply w0 & w1 in v1 by v2.w2. */
246 pResult->s.Hi += (uint32_t)pValue1->Words.w0 * pValue2->Words.w2;
247 pResult->Words.w3 += pValue1->Words.w1 * pValue2->Words.w2;
249 /* multiply w0 in v1 by v2.w3. */
250 pResult->Words.w3 += pValue1->Words.w0 * pValue2->Words.w3;
252 return pResult;
257 * Multiplies an 64-bit unsigned integer by a 32-bit unsigned integer value.
259 * @returns pResult
260 * @param pResult The result variable.
261 * @param pValue1 The first value.
262 * @param uValue2 The second value, 32-bit.
264 DECLINLINE(PRTUINT64U) RTUInt64MulByU32(PRTUINT64U pResult, PCRTUINT64U pValue1, uint32_t uValue2)
266 uint16_t const uLoValue2 = (uint16_t)uValue2;
267 uint16_t const uHiValue2 = (uint16_t)(uValue2 >> 16);
268 RTUINT32U uTmp;
270 /* multiply all words in v1 by uLoValue1. */
271 pResult->s.Lo = (uint32_t)pValue1->Words.w0 * uLoValue2;
273 uTmp.u = (uint32_t)pValue1->Words.w1 * uLoValue2;
274 pResult->Words.w3 = 0;
275 pResult->Words.w2 = uTmp.Words.w1;
276 pResult->Words.w1 += uTmp.Words.w0;
277 if (pResult->Words.w1 < uTmp.Words.w0)
278 if (pResult->Words.w2++ == UINT16_MAX)
279 pResult->Words.w3++;
281 pResult->s.Hi += (uint32_t)pValue1->Words.w2 * uLoValue2;
282 pResult->Words.w3 += pValue1->Words.w3 * uLoValue2;
284 /* multiply w0, w1 & w2 in v1 by uHiValue2. */
285 uTmp.u = (uint32_t)pValue1->Words.w0 * uHiValue2;
286 pResult->Words.w1 += uTmp.Words.w0;
287 if (pResult->Words.w1 < uTmp.Words.w0)
288 if (pResult->Words.w2++ == UINT16_MAX)
289 pResult->Words.w3++;
291 pResult->Words.w2 += uTmp.Words.w1;
292 if (pResult->Words.w2 < uTmp.Words.w1)
293 pResult->Words.w3++;
295 pResult->s.Hi += (uint32_t)pValue1->Words.w1 * uHiValue2;
296 pResult->Words.w3 += pValue1->Words.w2 * uHiValue2;
298 return pResult;
303 * Multiplies two 32-bit unsigned integer values with 64-bit precision.
305 * @returns pResult
306 * @param pResult The result variable.
307 * @param uValue1 The first value. 32-bit.
308 * @param uValue2 The second value, 32-bit.
310 DECLINLINE(PRTUINT64U) RTUInt64MulU32ByU32(PRTUINT64U pResult, uint32_t uValue1, uint32_t uValue2)
312 uint16_t const uLoValue1 = (uint16_t)uValue1;
313 uint16_t const uHiValue1 = (uint16_t)(uValue1 >> 16);
314 uint16_t const uLoValue2 = (uint16_t)uValue2;
315 uint16_t const uHiValue2 = (uint16_t)(uValue2 >> 16);
316 RTUINT32U uTmp;
318 /* Multiply uLoValue1 and uHiValue1 by uLoValue1. */
319 pResult->s.Lo = (uint32_t)uLoValue1 * uLoValue2;
321 uTmp.u = (uint32_t)uHiValue1 * uLoValue2;
322 pResult->Words.w3 = 0;
323 pResult->Words.w2 = uTmp.Words.w1;
324 pResult->Words.w1 += uTmp.Words.w0;
325 if (pResult->Words.w1 < uTmp.Words.w0)
326 if (pResult->Words.w2++ == UINT16_MAX)
327 pResult->Words.w3++;
329 /* Multiply uLoValue1 and uHiValue1 by uHiValue2. */
330 uTmp.u = (uint32_t)uLoValue1 * uHiValue2;
331 pResult->Words.w1 += uTmp.Words.w0;
332 if (pResult->Words.w1 < uTmp.Words.w0)
333 if (pResult->Words.w2++ == UINT16_MAX)
334 pResult->Words.w3++;
336 pResult->Words.w2 += uTmp.Words.w1;
337 if (pResult->Words.w2 < uTmp.Words.w1)
338 pResult->Words.w3++;
340 pResult->s.Hi += (uint32_t)uHiValue1 * uHiValue2;
341 return pResult;
345 DECLINLINE(PRTUINT64U) RTUInt64DivRem(PRTUINT64U pQuotient, PRTUINT64U pRemainder, PCRTUINT64U pValue1, PCRTUINT64U pValue2);
346 DECLINLINE(PRTUINT64U) RTUInt64DivRemSigned(PRTUINT64U pQuotient, PRTUINT64U pRemainder, PCRTUINT64U pValue1, PCRTUINT64U pValue2);
349 * Divides a 64-bit unsigned integer value by another.
351 * @returns pResult
352 * @param pResult The result variable.
353 * @param pValue1 The dividend value.
354 * @param pValue2 The divisor value.
356 DECLINLINE(PRTUINT64U) RTUInt64Div(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
358 RTUINT64U Ignored;
359 return RTUInt64DivRem(pResult, &Ignored, pValue1, pValue2);
364 * Divides a 64-bit unsigned integer value by another, returning the remainder.
366 * @returns pResult
367 * @param pResult The result variable (remainder).
368 * @param pValue1 The dividend value.
369 * @param pValue2 The divisor value.
371 DECLINLINE(PRTUINT64U) RTUInt64Mod(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
373 RTUINT64U Ignored;
374 RTUInt64DivRem(&Ignored, pResult, pValue1, pValue2);
375 return pResult;
380 * Divides a 64-bit signed integer value by another.
382 * @returns pResult
383 * @param pResult The result variable.
384 * @param pValue1 The dividend value.
385 * @param pValue2 The divisor value.
387 DECLINLINE(PRTUINT64U) RTUInt64DivSigned(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
389 RTUINT64U Ignored;
390 return RTUInt64DivRemSigned(pResult, &Ignored, pValue1, pValue2);
395 * Divides a 64-bit unsigned integer value by another, returning the remainder.
397 * @returns pResult
398 * @param pResult The result variable (remainder).
399 * @param pValue1 The dividend value.
400 * @param pValue2 The divisor value.
402 DECLINLINE(PRTUINT64U) RTUInt64ModSigned(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
404 RTUINT64U Ignored;
405 RTUInt64DivRemSigned(&Ignored, pResult, pValue1, pValue2);
406 return pResult;
411 * Bitwise AND of two 64-bit unsigned integer values.
413 * @returns pResult
414 * @param pResult The result variable.
415 * @param pValue1 The first value.
416 * @param pValue2 The second value.
418 DECLINLINE(PRTUINT64U) RTUInt64And(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
420 pResult->s.Hi = pValue1->s.Hi & pValue2->s.Hi;
421 pResult->s.Lo = pValue1->s.Lo & pValue2->s.Lo;
422 return pResult;
427 * Bitwise OR of two 64-bit unsigned integer values.
429 * @returns pResult
430 * @param pResult The result variable.
431 * @param pValue1 The first value.
432 * @param pValue2 The second value.
434 DECLINLINE(PRTUINT64U) RTUInt64Or( PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
436 pResult->s.Hi = pValue1->s.Hi | pValue2->s.Hi;
437 pResult->s.Lo = pValue1->s.Lo | pValue2->s.Lo;
438 return pResult;
443 * Bitwise XOR of two 64-bit unsigned integer values.
445 * @returns pResult
446 * @param pResult The result variable.
447 * @param pValue1 The first value.
448 * @param pValue2 The second value.
450 DECLINLINE(PRTUINT64U) RTUInt64Xor(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
452 pResult->s.Hi = pValue1->s.Hi ^ pValue2->s.Hi;
453 pResult->s.Lo = pValue1->s.Lo ^ pValue2->s.Lo;
454 return pResult;
459 * Shifts a 64-bit unsigned integer value @a cBits to the left.
461 * @returns pResult
462 * @param pResult The result variable.
463 * @param pValue The value to shift.
464 * @param cBits The number of bits to shift it.
466 DECLINLINE(PRTUINT64U) RTUInt64ShiftLeft(PRTUINT64U pResult, PCRTUINT64U pValue, int cBits)
468 cBits &= 63;
469 if (cBits < 32)
471 pResult->s.Lo = pValue->s.Lo << cBits;
472 pResult->s.Hi = (pValue->s.Hi << cBits) | (pValue->s.Lo >> (32 - cBits));
474 else
476 pResult->s.Lo = 0;
477 pResult->s.Hi = pValue->s.Lo << (cBits - 32);
479 return pResult;
484 * Shifts a 64-bit unsigned integer value @a cBits to the right.
486 * @returns pResult
487 * @param pResult The result variable.
488 * @param pValue The value to shift.
489 * @param cBits The number of bits to shift it.
491 DECLINLINE(PRTUINT64U) RTUInt64ShiftRight(PRTUINT64U pResult, PCRTUINT64U pValue, int cBits)
493 cBits &= 63;
494 if (cBits < 32)
496 pResult->s.Hi = pValue->s.Hi >> cBits;
497 pResult->s.Lo = (pValue->s.Lo >> cBits) | (pValue->s.Hi << (32 - cBits));
499 else
501 pResult->s.Hi = 0;
502 pResult->s.Lo = pValue->s.Hi >> (cBits - 32);
504 return pResult;
509 * Boolean not (result 0 or 1).
511 * @returns pResult.
512 * @param pResult The result variable.
513 * @param pValue The value.
515 DECLINLINE(PRTUINT64U) RTUInt64BooleanNot(PRTUINT64U pResult, PCRTUINT64U pValue)
517 pResult->s.Lo = pValue->s.Lo || pValue->s.Hi ? 0 : 1;
518 pResult->s.Hi = 0;
519 return pResult;
524 * Bitwise not (flips each bit of the 64 bits).
526 * @returns pResult.
527 * @param pResult The result variable.
528 * @param pValue The value.
530 DECLINLINE(PRTUINT64U) RTUInt64BitwiseNot(PRTUINT64U pResult, PCRTUINT64U pValue)
532 pResult->s.Hi = ~pValue->s.Hi;
533 pResult->s.Lo = ~pValue->s.Lo;
534 return pResult;
539 * Assigns one 64-bit unsigned integer value to another.
541 * @returns pResult
542 * @param pResult The result variable.
543 * @param pValue The value to assign.
545 DECLINLINE(PRTUINT64U) RTUInt64Assign(PRTUINT64U pResult, PCRTUINT64U pValue)
547 #if ARCH_BITS >= 32
548 pResult->s.Hi = pValue->s.Hi;
549 pResult->s.Lo = pValue->s.Lo;
550 #else
551 pResult->Words.w0 = pValue->Words.w0;
552 pResult->Words.w1 = pValue->Words.w1;
553 pResult->Words.w2 = pValue->Words.w2;
554 pResult->Words.w3 = pValue->Words.w3;
555 #endif
556 return pResult;
561 * Assigns a boolean value to 64-bit unsigned integer.
563 * @returns pValueResult
564 * @param pValueResult The result variable.
565 * @param fValue The boolean value.
567 DECLINLINE(PRTUINT64U) RTUInt64AssignBoolean(PRTUINT64U pValueResult, bool fValue)
569 #if ARCH_BITS >= 32
570 pValueResult->s.Lo = fValue;
571 pValueResult->s.Hi = 0;
572 #else
573 pValueResult->Words.w0 = fValue;
574 pValueResult->Words.w1 = 0;
575 pValueResult->Words.w2 = 0;
576 pValueResult->Words.w3 = 0;
577 #endif
578 return pValueResult;
583 * Assigns a 8-bit unsigned integer value to 64-bit unsigned integer.
585 * @returns pValueResult
586 * @param pValueResult The result variable.
587 * @param u8Value The 8-bit unsigned integer value.
589 DECLINLINE(PRTUINT64U) RTUInt64AssignU8(PRTUINT64U pValueResult, uint8_t u8Value)
591 #if ARCH_BITS >= 32
592 pValueResult->s.Lo = u8Value;
593 pValueResult->s.Hi = 0;
594 #else
595 pValueResult->Words.w0 = u8Value;
596 pValueResult->Words.w1 = 0;
597 pValueResult->Words.w2 = 0;
598 pValueResult->Words.w3 = 0;
599 #endif
600 return pValueResult;
605 * Assigns a 16-bit unsigned integer value to 64-bit unsigned integer.
607 * @returns pValueResult
608 * @param pValueResult The result variable.
609 * @param u16Value The 16-bit unsigned integer value.
611 DECLINLINE(PRTUINT64U) RTUInt64AssignU16(PRTUINT64U pValueResult, uint16_t u16Value)
613 #if ARCH_BITS >= 32
614 pValueResult->s.Lo = u16Value;
615 pValueResult->s.Hi = 0;
616 #else
617 pValueResult->Words.w0 = u16Value;
618 pValueResult->Words.w1 = 0;
619 pValueResult->Words.w2 = 0;
620 pValueResult->Words.w3 = 0;
621 #endif
622 return pValueResult;
627 * Assigns a 32-bit unsigned integer value to 64-bit unsigned integer.
629 * @returns pValueResult
630 * @param pValueResult The result variable.
631 * @param u32Value The 32-bit unsigned integer value.
633 DECLINLINE(PRTUINT64U) RTUInt64AssignU32(PRTUINT64U pValueResult, uint32_t u32Value)
635 #if ARCH_BITS >= 32
636 pValueResult->s.Lo = u32Value;
637 pValueResult->s.Hi = 0;
638 #else
639 pValueResult->Words.w0 = (uint16_t)u32Value;
640 pValueResult->Words.w1 = u32Value >> 16;
641 pValueResult->Words.w2 = 0;
642 pValueResult->Words.w3 = 0;
643 #endif
644 return pValueResult;
649 * Adds two 64-bit unsigned integer values, storing the result in the first.
651 * @returns pValue1Result.
652 * @param pValue1Result The first value and result.
653 * @param pValue2 The second value.
655 DECLINLINE(PRTUINT64U) RTUInt64AssignAdd(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
657 uint32_t const uTmp = pValue1Result->s.Lo;
658 pValue1Result->s.Lo += pValue2->s.Lo;
659 if (pValue1Result->s.Lo < uTmp)
660 pValue1Result->s.Hi++;
661 pValue1Result->s.Hi += pValue2->s.Hi;
662 return pValue1Result;
667 * Subtracts two 64-bit unsigned integer values, storing the result in the
668 * first.
670 * @returns pValue1Result.
671 * @param pValue1Result The minuend value and result.
672 * @param pValue2 The subtrahend value.
674 DECLINLINE(PRTUINT64U) RTUInt64AssignSub(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
676 uint32_t const uTmp = pValue1Result->s.Lo;
677 pValue1Result->s.Lo -= pValue2->s.Lo;
678 if (pValue1Result->s.Lo > uTmp)
679 pValue1Result->s.Hi--;
680 pValue1Result->s.Hi -= pValue2->s.Hi;
681 return pValue1Result;
686 * Negates a 64-bit unsigned integer value, returning the result in place.
688 * @returns pValueResult.
689 * @param pValueResult The value and result.
691 DECLINLINE(PRTUINT64U) RTUInt64AssignNeg(PRTUINT64U pValueResult)
693 pValueResult->s.Lo = UINT32_C(0) - pValueResult->s.Lo;
694 pValueResult->s.Hi = UINT32_C(0) - pValueResult->s.Hi;
695 if (pValueResult->s.Lo > UINT32_C(0))
696 pValueResult->s.Hi--;
697 return pValueResult;
702 * Multiplies two 64-bit unsigned integer values, storing the result in the
703 * first.
705 * @returns pValue1Result.
706 * @param pValue1Result The first value and result.
707 * @param pValue2 The second value.
709 DECLINLINE(PRTUINT64U) RTUInt64AssignMul(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
711 RTUINT64U Result;
712 RTUInt64Mul(&Result, pValue1Result, pValue2);
713 *pValue1Result = Result;
714 return pValue1Result;
719 * Divides a 64-bit unsigned integer value by another, storing the result in
720 * the first.
722 * @returns pValue1Result.
723 * @param pValue1Result The dividend value and result.
724 * @param pValue2 The divisor value.
726 DECLINLINE(PRTUINT64U) RTUInt64AssignDiv(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
728 RTUINT64U Result;
729 RTUINT64U Ignored;
730 RTUInt64DivRem(&Result, &Ignored, pValue1Result, pValue2);
731 *pValue1Result = Result;
732 return pValue1Result;
737 * Divides a 64-bit unsigned integer value by another, storing the remainder in
738 * the first.
740 * @returns pValue1Result.
741 * @param pValue1Result The dividend value and result (remainder).
742 * @param pValue2 The divisor value.
744 DECLINLINE(PRTUINT64U) RTUInt64AssignMod(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
746 RTUINT64U Ignored;
747 RTUINT64U Result;
748 RTUInt64DivRem(&Ignored, &Result, pValue1Result, pValue2);
749 *pValue1Result = Result;
750 return pValue1Result;
755 * Performs a bitwise AND of two 64-bit unsigned integer values and assigned
756 * the result to the first one.
758 * @returns pValue1Result.
759 * @param pValue1Result The first value and result.
760 * @param pValue2 The second value.
762 DECLINLINE(PRTUINT64U) RTUInt64AssignAnd(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
764 #if ARCH_BITS >= 32
765 pValue1Result->s.Hi &= pValue2->s.Hi;
766 pValue1Result->s.Lo &= pValue2->s.Lo;
767 #else
768 pValue1Result->Words.w0 &= pValue2->Words.w0;
769 pValue1Result->Words.w1 &= pValue2->Words.w1;
770 pValue1Result->Words.w2 &= pValue2->Words.w2;
771 pValue1Result->Words.w3 &= pValue2->Words.w3;
772 #endif
773 return pValue1Result;
778 * Performs a bitwise AND of a 64-bit unsigned integer value and a mask made
779 * up of the first N bits, assigning the result to the the 64-bit value.
781 * @returns pValueResult.
782 * @param pValueResult The value and result.
783 * @param cBits The number of bits to AND (counting from the first
784 * bit).
786 DECLINLINE(PRTUINT64U) RTUInt64AssignAndNFirstBits(PRTUINT64U pValueResult, unsigned cBits)
788 if (cBits <= 32)
790 if (cBits != 32)
791 pValueResult->s.Lo &= (RT_BIT_32(cBits) - 1);
792 pValueResult->s.Hi = 0;
794 else if (cBits < 64)
795 pValueResult->s.Hi &= (RT_BIT_32(cBits - 32) - 1);
796 return pValueResult;
801 * Performs a bitwise OR of two 64-bit unsigned integer values and assigned
802 * the result to the first one.
804 * @returns pValue1Result.
805 * @param pValue1Result The first value and result.
806 * @param pValue2 The second value.
808 DECLINLINE(PRTUINT64U) RTUInt64AssignOr(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
810 #if ARCH_BITS >= 32
811 pValue1Result->s.Hi |= pValue2->s.Hi;
812 pValue1Result->s.Lo |= pValue2->s.Lo;
813 #else
814 pValue1Result->Words.w0 |= pValue2->Words.w0;
815 pValue1Result->Words.w1 |= pValue2->Words.w1;
816 pValue1Result->Words.w2 |= pValue2->Words.w2;
817 pValue1Result->Words.w3 |= pValue2->Words.w3;
818 #endif
819 return pValue1Result;
824 * ORs in a bit and assign the result to the input value.
826 * @returns pValue1Result.
827 * @param pValue1Result The first value and result.
828 * @param iBit The bit to set (0 based).
830 DECLINLINE(PRTUINT64U) RTUInt64AssignOrBit(PRTUINT64U pValue1Result, unsigned iBit)
832 #if ARCH_BITS >= 32
833 if (iBit >= 32)
834 pValue1Result->s.Hi |= RT_BIT_32(iBit - 32);
835 else
836 pValue1Result->s.Lo |= RT_BIT_32(iBit);
837 #else
838 if (iBit >= 32)
840 if (iBit >= 48)
841 pValue1Result->Words.w3 |= UINT16_C(1) << (iBit - 48);
842 else
843 pValue1Result->Words.w2 |= UINT16_C(1) << (iBit - 32);
845 else
847 if (iBit >= 16)
848 pValue1Result->Words.w1 |= UINT16_C(1) << (iBit - 16);
849 else
850 pValue1Result->Words.w0 |= UINT16_C(1) << (iBit);
852 #endif
853 return pValue1Result;
859 * Performs a bitwise XOR of two 64-bit unsigned integer values and assigned
860 * the result to the first one.
862 * @returns pValue1Result.
863 * @param pValue1Result The first value and result.
864 * @param pValue2 The second value.
866 DECLINLINE(PRTUINT64U) RTUInt64AssignXor(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
868 #if ARCH_BITS >= 32
869 pValue1Result->s.Hi ^= pValue2->s.Hi;
870 pValue1Result->s.Lo ^= pValue2->s.Lo;
871 #else
872 pValue1Result->Words.w0 ^= pValue2->Words.w0;
873 pValue1Result->Words.w1 ^= pValue2->Words.w1;
874 pValue1Result->Words.w2 ^= pValue2->Words.w2;
875 pValue1Result->Words.w3 ^= pValue2->Words.w3;
876 #endif
877 return pValue1Result;
882 * Performs a bitwise left shift on a 64-bit unsigned integer value, assigning
883 * the result to it.
885 * @returns pValueResult.
886 * @param pValueResult The first value and result.
887 * @param cBits The number of bits to shift.
889 DECLINLINE(PRTUINT64U) RTUInt64AssignShiftLeft(PRTUINT64U pValueResult, int cBits)
891 RTUINT64U const InVal = *pValueResult;
892 if (cBits > 0)
894 /* (left shift) */
895 cBits &= 63;
896 if (cBits >= 32)
898 pValueResult->s.Lo = 0;
899 pValueResult->s.Hi = InVal.s.Lo << (cBits - 32);
901 else
903 pValueResult->s.Hi = InVal.s.Hi << cBits;
904 pValueResult->s.Hi |= InVal.s.Lo >> (32 - cBits);
905 pValueResult->s.Lo = InVal.s.Lo << cBits;
908 else if (cBits < 0)
910 /* (right shift) */
911 cBits = -cBits;
912 cBits &= 63;
913 if (cBits >= 32)
915 pValueResult->s.Hi = 0;
916 pValueResult->s.Lo = InVal.s.Hi >> (cBits - 32);
918 else
920 pValueResult->s.Lo = InVal.s.Lo >> cBits;
921 pValueResult->s.Lo |= InVal.s.Hi << (32 - cBits);
922 pValueResult->s.Hi = InVal.s.Hi >> cBits;
925 return pValueResult;
930 * Performs a bitwise left shift on a 64-bit unsigned integer value, assigning
931 * the result to it.
933 * @returns pValueResult.
934 * @param pValueResult The first value and result.
935 * @param cBits The number of bits to shift.
937 DECLINLINE(PRTUINT64U) RTUInt64AssignShiftRight(PRTUINT64U pValueResult, int cBits)
939 return RTUInt64AssignShiftLeft(pValueResult, -cBits);
944 * Performs a bitwise NOT on a 64-bit unsigned integer value, assigning the
945 * result to it.
947 * @returns pValueResult
948 * @param pValueResult The value and result.
950 DECLINLINE(PRTUINT64U) RTUInt64AssignBitwiseNot(PRTUINT64U pValueResult)
952 #if ARCH_BITS >= 32
953 pValueResult->s.Hi = ~pValueResult->s.Hi;
954 pValueResult->s.Lo = ~pValueResult->s.Lo;
955 #else
956 pValueResult->Words.w0 = ~pValueResult->Words.w0;
957 pValueResult->Words.w1 = ~pValueResult->Words.w1;
958 pValueResult->Words.w2 = ~pValueResult->Words.w2;
959 pValueResult->Words.w3 = ~pValueResult->Words.w3;
960 #endif
961 return pValueResult;
966 * Performs a boolean NOT on a 64-bit unsigned integer value, assigning the
967 * result to it.
969 * @returns pValueResult
970 * @param pValueResult The value and result.
972 DECLINLINE(PRTUINT64U) RTUInt64AssignBooleanNot(PRTUINT64U pValueResult)
974 return RTUInt64AssignBoolean(pValueResult, RTUInt64IsZero(pValueResult));
979 * Compares two 64-bit unsigned integer values.
981 * @retval 0 if equal.
982 * @retval -1 if the first value is smaller than the second.
983 * @retval 1 if the first value is larger than the second.
985 * @param pValue1 The first value.
986 * @param pValue2 The second value.
988 DECLINLINE(int) RTUInt64Compare(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
990 #if ARCH_BITS >= 32
991 if (pValue1->s.Hi != pValue2->s.Hi)
992 return pValue1->s.Hi > pValue2->s.Hi ? 1 : -1;
993 if (pValue1->s.Lo != pValue2->s.Lo)
994 return pValue1->s.Lo > pValue2->s.Lo ? 1 : -1;
995 return 0;
996 #else
997 if (pValue1->Words.w3 != pValue2->Words.w3)
998 return pValue1->Words.w3 > pValue2->Words.w3 ? 1 : -1;
999 if (pValue1->Words.w2 != pValue2->Words.w2)
1000 return pValue1->Words.w2 > pValue2->Words.w2 ? 1 : -1;
1001 if (pValue1->Words.w1 != pValue2->Words.w1)
1002 return pValue1->Words.w1 > pValue2->Words.w1 ? 1 : -1;
1003 if (pValue1->Words.w0 != pValue2->Words.w0)
1004 return pValue1->Words.w0 > pValue2->Words.w0 ? 1 : -1;
1005 return 0;
1006 #endif
1011 * Tests if a 64-bit unsigned integer value is smaller than another.
1013 * @returns true if the first value is smaller, false if not.
1014 * @param pValue1 The first value.
1015 * @param pValue2 The second value.
1017 DECLINLINE(bool) RTUInt64IsSmaller(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1019 #if ARCH_BITS >= 32
1020 return pValue1->s.Hi < pValue2->s.Hi
1021 || ( pValue1->s.Hi == pValue2->s.Hi
1022 && pValue1->s.Lo < pValue2->s.Lo);
1023 #else
1024 return pValue1->Words.w3 < pValue2->Words.w3
1025 || ( pValue1->Words.w3 == pValue2->Words.w3
1026 && ( pValue1->Words.w2 < pValue2->Words.w2
1027 || ( pValue1->Words.w2 == pValue2->Words.w2
1028 && ( pValue1->Words.w1 < pValue2->Words.w1
1029 || ( pValue1->Words.w1 == pValue2->Words.w1
1030 && pValue1->Words.w0 < pValue2->Words.w0)))));
1031 #endif
1036 * Tests if a 32-bit unsigned integer value is larger than another.
1038 * @returns true if the first value is larger, false if not.
1039 * @param pValue1 The first value.
1040 * @param pValue2 The second value.
1042 DECLINLINE(bool) RTUInt64IsLarger(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1044 #if ARCH_BITS >= 32
1045 return pValue1->s.Hi > pValue2->s.Hi
1046 || ( pValue1->s.Hi == pValue2->s.Hi
1047 && pValue1->s.Lo > pValue2->s.Lo);
1048 #else
1049 return pValue1->Words.w3 > pValue2->Words.w3
1050 || ( pValue1->Words.w3 == pValue2->Words.w3
1051 && ( pValue1->Words.w2 > pValue2->Words.w2
1052 || ( pValue1->Words.w2 == pValue2->Words.w2
1053 && ( pValue1->Words.w1 > pValue2->Words.w1
1054 || ( pValue1->Words.w1 == pValue2->Words.w1
1055 && pValue1->Words.w0 > pValue2->Words.w0)))));
1056 #endif
1061 * Tests if a 64-bit unsigned integer value is larger or equal than another.
1063 * @returns true if the first value is larger or equal, false if not.
1064 * @param pValue1 The first value.
1065 * @param pValue2 The second value.
1067 DECLINLINE(bool) RTUInt64IsLargerOrEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1069 #if ARCH_BITS >= 32
1070 return pValue1->s.Hi > pValue2->s.Hi
1071 || ( pValue1->s.Hi == pValue2->s.Hi
1072 && pValue1->s.Lo >= pValue2->s.Lo);
1073 #else
1074 return pValue1->Words.w3 > pValue2->Words.w3
1075 || ( pValue1->Words.w3 == pValue2->Words.w3
1076 && ( pValue1->Words.w2 > pValue2->Words.w2
1077 || ( pValue1->Words.w2 == pValue2->Words.w2
1078 && ( pValue1->Words.w1 > pValue2->Words.w1
1079 || ( pValue1->Words.w1 == pValue2->Words.w1
1080 && pValue1->Words.w0 >= pValue2->Words.w0)))));
1081 #endif
1086 * Tests if two 64-bit unsigned integer values not equal.
1088 * @returns true if equal, false if not equal.
1089 * @param pValue1 The first value.
1090 * @param pValue2 The second value.
1092 DECLINLINE(bool) RTUInt64IsEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1094 #if ARCH_BITS >= 32
1095 return pValue1->s.Hi == pValue2->s.Hi
1096 && pValue1->s.Lo == pValue2->s.Lo;
1097 #else
1098 return pValue1->Words.w0 == pValue2->Words.w0
1099 && pValue1->Words.w1 == pValue2->Words.w1
1100 && pValue1->Words.w2 == pValue2->Words.w2
1101 && pValue1->Words.w3 == pValue2->Words.w3;
1102 #endif
1107 * Tests if two 64-bit unsigned integer values are not equal.
1109 * @returns true if not equal, false if equal.
1110 * @param pValue1 The first value.
1111 * @param pValue2 The second value.
1113 DECLINLINE(bool) RTUInt64IsNotEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1115 return !RTUInt64IsEqual(pValue1, pValue2);
1120 * Sets a bit in a 64-bit unsigned integer type.
1122 * @returns pValueResult.
1123 * @param pValueResult The input and output value.
1124 * @param iBit The bit to set.
1126 DECLINLINE(PRTUINT64U) RTUInt64BitSet(PRTUINT64U pValueResult, unsigned iBit)
1128 if (iBit < 32)
1130 #if ARCH_BITS >= 32
1131 pValueResult->s.Lo |= RT_BIT_32(iBit);
1132 #else
1133 if (iBit < 16)
1134 pValueResult->Words.w0 |= UINT16_C(1) << iBit;
1135 else
1136 pValueResult->Words.w1 |= UINT16_C(1) << (iBit - 32);
1137 #endif
1139 else if (iBit < 64)
1141 #if ARCH_BITS >= 32
1142 pValueResult->s.Hi |= RT_BIT_32(iBit - 32);
1143 #else
1144 if (iBit < 48)
1145 pValueResult->Words.w2 |= UINT16_C(1) << (iBit - 64);
1146 else
1147 pValueResult->Words.w3 |= UINT16_C(1) << (iBit - 96);
1148 #endif
1150 return pValueResult;
1155 * Sets a bit in a 64-bit unsigned integer type.
1157 * @returns pValueResult.
1158 * @param pValueResult The input and output value.
1159 * @param iBit The bit to set.
1161 DECLINLINE(PRTUINT64U) RTUInt64BitClear(PRTUINT64U pValueResult, unsigned iBit)
1163 if (iBit < 32)
1165 #if ARCH_BITS >= 32
1166 pValueResult->s.Lo &= ~RT_BIT_32(iBit);
1167 #else
1168 if (iBit < 48)
1169 pValueResult->Words.w0 &= ~(UINT16_C(1) << (iBit));
1170 else
1171 pValueResult->Words.w1 &= ~(UINT16_C(1) << (iBit - 32));
1172 #endif
1174 else if (iBit < 64)
1176 #if ARCH_BITS >= 32
1177 pValueResult->s.Hi &= ~RT_BIT_32(iBit - 32);
1178 #else
1179 if (iBit < 48)
1180 pValueResult->Words.w2 &= ~(UINT16_C(1) << (iBit - 64));
1181 else
1182 pValueResult->Words.w3 &= ~(UINT16_C(1) << (iBit - 96));
1183 #endif
1185 return pValueResult;
1190 * Tests if a bit in a 64-bit unsigned integer value is set.
1192 * @returns pValueResult.
1193 * @param pValueResult The input and output value.
1194 * @param iBit The bit to test.
1196 DECLINLINE(bool) RTUInt64BitTest(PRTUINT64U pValueResult, unsigned iBit)
1198 bool fRc;
1199 if (iBit < 32)
1201 #if ARCH_BITS >= 32
1202 fRc = RT_BOOL(pValueResult->s.Lo & RT_BIT_32(iBit));
1203 #else
1204 if (iBit < 16)
1205 fRc = RT_BOOL(pValueResult->Words.w0 & (UINT16_C(1) << (iBit)));
1206 else
1207 fRc = RT_BOOL(pValueResult->Words.w1 & (UINT16_C(1) << (iBit - 16)));
1208 #endif
1210 else if (iBit < 64)
1212 #if ARCH_BITS >= 32
1213 fRc = RT_BOOL(pValueResult->s.Hi & RT_BIT_32(iBit - 32));
1214 #else
1215 if (iBit < 48)
1216 fRc = RT_BOOL(pValueResult->Words.w2 & (UINT16_C(1) << (iBit - 32)));
1217 else
1218 fRc = RT_BOOL(pValueResult->Words.w3 & (UINT16_C(1) << (iBit - 48)));
1219 #endif
1221 else
1222 fRc = false;
1223 return fRc;
1228 * Set a range of bits a 64-bit unsigned integer value.
1230 * @returns pValueResult.
1231 * @param pValueResult The input and output value.
1232 * @param iFirstBit The first bit to test.
1233 * @param cBits The number of bits to set.
1235 DECLINLINE(PRTUINT64U) RTUInt64BitSetRange(PRTUINT64U pValueResult, unsigned iFirstBit, unsigned cBits)
1237 /* bounds check & fix. */
1238 if (iFirstBit < 64)
1240 if (iFirstBit + cBits > 64)
1241 cBits = 64 - iFirstBit;
1243 #if ARCH_BITS >= 32
1244 if (iFirstBit + cBits < 32)
1245 pValueResult->s.Lo |= (RT_BIT_32(cBits) - 1) << iFirstBit;
1246 else if (iFirstBit + cBits < 64 && iFirstBit >= 32)
1247 pValueResult->s.Hi |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 32);
1248 else
1249 #else
1250 if (iFirstBit + cBits < 16)
1251 pValueResult->Words.w0 |= ((UINT16_C(1) << cBits) - 1) << iFirstBit;
1252 else if (iFirstBit + cBits < 32 && iFirstBit >= 16)
1253 pValueResult->Words.w1 |= ((UINT16_C(1) << cBits) - 1) << (iFirstBit - 16);
1254 else if (iFirstBit + cBits < 48 && iFirstBit >= 32)
1255 pValueResult->Words.w2 |= ((UINT16_C(1) << cBits) - 1) << (iFirstBit - 32);
1256 else if (iFirstBit + cBits < 64 && iFirstBit >= 48)
1257 pValueResult->Words.w3 |= ((UINT16_C(1) << cBits) - 1) << (iFirstBit - 48);
1258 else
1259 #endif
1260 while (cBits-- > 0)
1261 RTUInt64BitSet(pValueResult, iFirstBit++);
1263 return pValueResult;
1268 * Test if all the bits of a 64-bit unsigned integer value are set.
1270 * @returns true if they are, false if they aren't.
1271 * @param pValue The input and output value.
1273 DECLINLINE(bool) RTUInt64BitAreAllSet(PRTUINT64U pValue)
1275 #if ARCH_BITS >= 32
1276 return pValue->s.Hi == UINT32_MAX
1277 && pValue->s.Lo == UINT32_MAX;
1278 #else
1279 return pValue->Words.w0 == UINT16_MAX
1280 && pValue->Words.w1 == UINT16_MAX
1281 && pValue->Words.w2 == UINT16_MAX
1282 && pValue->Words.w3 == UINT16_MAX;
1283 #endif
1288 * Test if all the bits of a 64-bit unsigned integer value are clear.
1290 * @returns true if they are, false if they aren't.
1291 * @param pValue The input and output value.
1293 DECLINLINE(bool) RTUInt64BitAreAllClear(PRTUINT64U pValue)
1295 return RTUInt64IsZero(pValue);
1299 DECLINLINE(unsigned) RTUInt64BitCount(PCRTUINT64U pValue)
1301 unsigned cBits;
1302 if (pValue->s.Hi != 0)
1304 #if ARCH_BITS >= 32
1305 cBits = 32 + ASMBitLastSetU32(pValue->s.Hi);
1306 #else
1307 if (pValue->Words.w3)
1308 cBits = 48 + ASMBitLastSetU16(pValue->Words.w3);
1309 else
1310 cBits = 32 + ASMBitLastSetU16(pValue->Words.w2);
1311 #endif
1313 else
1315 #if ARCH_BITS >= 32
1316 cBits = ASMBitLastSetU32(pValue->s.Lo);
1317 #else
1318 if (pValue->Words.w1)
1319 cBits = 16 + ASMBitLastSetU16(pValue->Words.w1);
1320 else
1321 cBits = 0 + ASMBitLastSetU16(pValue->Words.w0);
1322 #endif
1324 return cBits;
1329 * Divides a 64-bit unsigned integer value by another, returning both quotient
1330 * and remainder.
1332 * @returns pQuotient, NULL if pValue2 is 0.
1333 * @param pQuotient Where to return the quotient.
1334 * @param pRemainder Where to return the remainder.
1335 * @param pValue1 The dividend value.
1336 * @param pValue2 The divisor value.
1338 DECLINLINE(PRTUINT64U) RTUInt64DivRem(PRTUINT64U pQuotient, PRTUINT64U pRemainder, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1340 int iDiff;
1343 * Sort out all the special cases first.
1345 /* Divide by zero or 1? */
1346 if (!pValue2->s.Hi)
1348 if (!pValue2->s.Lo)
1349 return NULL;
1351 if (pValue2->s.Lo == 1)
1353 RTUInt64SetZero(pRemainder);
1354 *pQuotient = *pValue1;
1355 return pQuotient;
1357 /** @todo RTUInt64DivModByU32 */
1360 /* Dividend is smaller? */
1361 iDiff = RTUInt64Compare(pValue1, pValue2);
1362 if (iDiff < 0)
1364 *pRemainder = *pValue1;
1365 RTUInt64SetZero(pQuotient);
1368 /* The values are equal? */
1369 else if (iDiff == 0)
1371 RTUInt64SetZero(pRemainder);
1372 RTUInt64AssignU8(pQuotient, 1);
1374 else
1377 * Prepare.
1379 unsigned iBitAdder = RTUInt64BitCount(pValue1) - RTUInt64BitCount(pValue2);
1380 RTUINT64U NormDivisor = *pValue2;
1381 if (iBitAdder)
1383 RTUInt64ShiftLeft(&NormDivisor, pValue2, iBitAdder);
1384 if (RTUInt64IsLarger(&NormDivisor, pValue1))
1386 RTUInt64AssignShiftRight(&NormDivisor, 1);
1387 iBitAdder--;
1390 else
1391 NormDivisor = *pValue2;
1393 RTUInt64SetZero(pQuotient);
1394 *pRemainder = *pValue1;
1397 * Do the division.
1399 if (RTUInt64IsLargerOrEqual(pRemainder, pValue2))
1401 for (;;)
1403 if (RTUInt64IsLargerOrEqual(pRemainder, &NormDivisor))
1405 RTUInt64AssignSub(pRemainder, &NormDivisor);
1406 RTUInt64AssignOrBit(pQuotient, iBitAdder);
1408 if (RTUInt64IsSmaller(pRemainder, pValue2))
1409 break;
1410 RTUInt64AssignShiftRight(&NormDivisor, 1);
1411 iBitAdder--;
1415 return pQuotient;
1420 * Divides a 64-bit signed integer value by another, returning both quotient and
1421 * remainder.
1423 * @returns pQuotient, NULL if pValue2 is 0.
1424 * @param pQuotient Where to return the quotient.
1425 * @param pRemainder Where to return the remainder.
1426 * @param pValue1 The dividend value.
1427 * @param pValue2 The divisor value.
1429 DECLINLINE(PRTUINT64U) RTUInt64DivRemSigned(PRTUINT64U pQuotient, PRTUINT64U pRemainder, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1432 * If both values are positive, we can do a straight unsigned division.
1434 if (!RTUInt64IsSigned(pValue1))
1436 if (!RTUInt64IsSigned(pValue2))
1437 return RTUInt64DivRem(pQuotient, pRemainder, pValue1, pValue2);
1440 * Negative divisor, Positive dividend:
1441 * negate the divisor, do unsigned division, and negate the quotient.
1444 RTUINT64U NegDivisor;
1445 RTUInt64DivRem(pQuotient, pRemainder, pValue1, RTUInt64Neg(&NegDivisor, pValue2));
1446 RTUInt64AssignNeg(pQuotient);
1449 else
1451 /* Negate the dividend to get a positive value. */
1452 RTUINT64U NegDividend;
1453 RTUInt64Neg(&NegDividend, pValue1);
1455 if (!RTUInt64IsSigned(pValue2))
1458 * Negative dividend, positive divisor:
1459 * Negate the dividend (above), do unsigned division, and negate both quotient and remainder
1461 RTUInt64DivRem(pQuotient, pRemainder, &NegDividend, pValue2);
1462 RTUInt64AssignNeg(pQuotient);
1464 else
1467 * Negative dividend, negative divisor:
1468 * Negate both dividend (above) and divisor, do unsigned division, and negate the remainder.
1470 RTUINT64U NegDivisor;
1471 RTUInt64DivRem(pQuotient, pRemainder, &NegDividend, RTUInt64Neg(&NegDivisor, pValue2));
1473 RTUInt64AssignNeg(pRemainder);
1475 return pQuotient;
1479 /** @} */
1481 RT_C_DECLS_END
1483 #endif /* !IPRT_INCLUDED_uint64_h */