VirtualBox

source: vbox/trunk/include/iprt/uint64.h@ 95897

Last change on this file since 95897 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.3 KB
Line 
1/** @file
2 * IPRT - RTUINT64U methods for old 32-bit and 16-bit compilers.
3 */
4
5/*
6 * Copyright (C) 2011-2022 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef IPRT_INCLUDED_uint64_h
27#define IPRT_INCLUDED_uint64_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/cdefs.h>
33#include <iprt/types.h>
34#include <iprt/asm.h>
35
36RT_C_DECLS_BEGIN
37
38/** @defgroup grp_rt_uint64 RTUInt64 - 64-bit Unsigned Integer Methods for ancient compilers
39 * @ingroup grp_rt
40 * @{
41 */
42
43
44/**
45 * Test if a 128-bit unsigned integer value is zero.
46 *
47 * @returns true if they are, false if they aren't.
48 * @param pValue The input and output value.
49 */
50DECLINLINE(bool) RTUInt64IsZero(PRTUINT64U pValue)
51{
52#if ARCH_BITS >= 32
53 return pValue->s.Lo == 0
54 && pValue->s.Hi == 0;
55#else
56 return pValue->Words.w0 == 0
57 && pValue->Words.w1 == 0
58 && pValue->Words.w2 == 0
59 && pValue->Words.w3 == 0;
60#endif
61}
62
63
64/**
65 * Set a 128-bit unsigned integer value to zero.
66 *
67 * @returns pResult
68 * @param pResult The result variable.
69 */
70DECLINLINE(PRTUINT64U) RTUInt64SetZero(PRTUINT64U pResult)
71{
72#if ARCH_BITS >= 32
73 pResult->s.Hi = 0;
74 pResult->s.Lo = 0;
75#else
76 pResult->Words.w0 = 0;
77 pResult->Words.w1 = 0;
78 pResult->Words.w2 = 0;
79 pResult->Words.w3 = 0;
80#endif
81 return pResult;
82}
83
84
85/**
86 * Set a 32-bit unsigned integer value to the maximum value.
87 *
88 * @returns pResult
89 * @param pResult The result variable.
90 */
91DECLINLINE(PRTUINT64U) RTUInt64SetMax(PRTUINT64U pResult)
92{
93#if ARCH_BITS >= 32
94 pResult->s.Hi = UINT32_MAX;
95 pResult->s.Lo = UINT32_MAX;
96#else
97 pResult->Words.w0 = UINT16_MAX;
98 pResult->Words.w1 = UINT16_MAX;
99 pResult->Words.w2 = UINT16_MAX;
100 pResult->Words.w3 = UINT16_MAX;
101#endif
102 return pResult;
103}
104
105
106
107
108/**
109 * Adds two 64-bit unsigned integer values.
110 *
111 * @returns pResult
112 * @param pResult The result variable.
113 * @param pValue1 The first value.
114 * @param pValue2 The second value.
115 */
116DECLINLINE(PRTUINT64U) RTUInt64Add(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
117{
118 pResult->s.Hi = pValue1->s.Hi + pValue2->s.Hi;
119 pResult->s.Lo = pValue1->s.Lo + pValue2->s.Lo;
120 if (pResult->s.Lo < pValue1->s.Lo)
121 pResult->s.Hi++;
122 return pResult;
123}
124
125
126/**
127 * Adds a 64-bit and a 32-bit unsigned integer values.
128 *
129 * @returns pResult
130 * @param pResult The result variable.
131 * @param pValue1 The first value.
132 * @param uValue2 The second value, 32-bit.
133 */
134DECLINLINE(PRTUINT64U) RTUInt64AddU32(PRTUINT64U pResult, PCRTUINT64U pValue1, uint32_t uValue2)
135{
136 pResult->s.Hi = pValue1->s.Hi;
137 pResult->s.Lo = pValue1->s.Lo + uValue2;
138 if (pResult->s.Lo < pValue1->s.Lo)
139 pResult->s.Hi++;
140 return pResult;
141}
142
143
144/**
145 * Subtracts a 64-bit unsigned integer value from another.
146 *
147 * @returns pResult
148 * @param pResult The result variable.
149 * @param pValue1 The minuend value.
150 * @param pValue2 The subtrahend value.
151 */
152DECLINLINE(PRTUINT64U) RTUInt64Sub(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
153{
154 pResult->s.Lo = pValue1->s.Lo - pValue2->s.Lo;
155 pResult->s.Hi = pValue1->s.Hi - pValue2->s.Hi;
156 if (pResult->s.Lo > pValue1->s.Lo)
157 pResult->s.Hi--;
158 return pResult;
159}
160
161
162/**
163 * Multiplies two 64-bit unsigned integer values.
164 *
165 * @returns pResult
166 * @param pResult The result variable.
167 * @param pValue1 The first value.
168 * @param pValue2 The second value.
169 */
170DECLINLINE(PRTUINT64U) RTUInt64Mul(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
171{
172 RTUINT32U uTmp;
173
174 /* multiply all words in v1 by v2.w0. */
175 pResult->s.Lo = (uint32_t)pValue1->Words.w0 * pValue2->Words.w0;
176
177 uTmp.u = (uint32_t)pValue1->Words.w1 * pValue2->Words.w0;
178 pResult->Words.w3 = 0;
179 pResult->Words.w2 = uTmp.Words.w1;
180 pResult->Words.w1 += uTmp.Words.w0;
181 if (pResult->Words.w1 < uTmp.Words.w0)
182 if (pResult->Words.w2++ == UINT16_MAX)
183 pResult->Words.w3++;
184
185 pResult->s.Hi += (uint32_t)pValue1->Words.w2 * pValue2->Words.w0;
186 pResult->Words.w3 += pValue1->Words.w3 * pValue2->Words.w0;
187
188 /* multiply w0, w1 & w2 in v1 by v2.w1. */
189 uTmp.u = (uint32_t)pValue1->Words.w0 * pValue2->Words.w1;
190 pResult->Words.w1 += uTmp.Words.w0;
191 if (pResult->Words.w1 < uTmp.Words.w0)
192 if (pResult->Words.w2++ == UINT16_MAX)
193 pResult->Words.w3++;
194
195 pResult->Words.w2 += uTmp.Words.w1;
196 if (pResult->Words.w2 < uTmp.Words.w1)
197 pResult->Words.w3++;
198
199 pResult->s.Hi += (uint32_t)pValue1->Words.w1 * pValue2->Words.w1;
200 pResult->Words.w3 += pValue1->Words.w2 * pValue2->Words.w1;
201
202 /* multiply w0 & w1 in v1 by v2.w2. */
203 pResult->s.Hi += (uint32_t)pValue1->Words.w0 * pValue2->Words.w2;
204 pResult->Words.w3 += pValue1->Words.w1 * pValue2->Words.w2;
205
206 /* multiply w0 in v1 by v2.w3. */
207 pResult->Words.w3 += pValue1->Words.w0 * pValue2->Words.w3;
208
209 return pResult;
210}
211
212
213/**
214 * Multiplies an 64-bit unsigned integer by a 32-bit unsigned integer value.
215 *
216 * @returns pResult
217 * @param pResult The result variable.
218 * @param pValue1 The first value.
219 * @param uValue2 The second value, 32-bit.
220 */
221DECLINLINE(PRTUINT64U) RTUInt64MulByU32(PRTUINT64U pResult, PCRTUINT64U pValue1, uint32_t uValue2)
222{
223 uint16_t const uLoValue2 = (uint16_t)uValue2;
224 uint16_t const uHiValue2 = (uint16_t)(uValue2 >> 16);
225 RTUINT32U uTmp;
226
227 /* multiply all words in v1 by uLoValue1. */
228 pResult->s.Lo = (uint32_t)pValue1->Words.w0 * uLoValue2;
229
230 uTmp.u = (uint32_t)pValue1->Words.w1 * uLoValue2;
231 pResult->Words.w3 = 0;
232 pResult->Words.w2 = uTmp.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++;
237
238 pResult->s.Hi += (uint32_t)pValue1->Words.w2 * uLoValue2;
239 pResult->Words.w3 += pValue1->Words.w3 * uLoValue2;
240
241 /* multiply w0, w1 & w2 in v1 by uHiValue2. */
242 uTmp.u = (uint32_t)pValue1->Words.w0 * uHiValue2;
243 pResult->Words.w1 += uTmp.Words.w0;
244 if (pResult->Words.w1 < uTmp.Words.w0)
245 if (pResult->Words.w2++ == UINT16_MAX)
246 pResult->Words.w3++;
247
248 pResult->Words.w2 += uTmp.Words.w1;
249 if (pResult->Words.w2 < uTmp.Words.w1)
250 pResult->Words.w3++;
251
252 pResult->s.Hi += (uint32_t)pValue1->Words.w1 * uHiValue2;
253 pResult->Words.w3 += pValue1->Words.w2 * uHiValue2;
254
255 return pResult;
256}
257
258
259/**
260 * Multiplies two 32-bit unsigned integer values with 64-bit precision.
261 *
262 * @returns pResult
263 * @param pResult The result variable.
264 * @param uValue1 The first value. 32-bit.
265 * @param uValue2 The second value, 32-bit.
266 */
267DECLINLINE(PRTUINT64U) RTUInt64MulU32ByU32(PRTUINT64U pResult, uint32_t uValue1, uint32_t uValue2)
268{
269 uint16_t const uLoValue1 = (uint16_t)uValue1;
270 uint16_t const uHiValue1 = (uint16_t)(uValue1 >> 16);
271 uint16_t const uLoValue2 = (uint16_t)uValue2;
272 uint16_t const uHiValue2 = (uint16_t)(uValue2 >> 16);
273 RTUINT32U uTmp;
274
275 /* Multiply uLoValue1 and uHiValue1 by uLoValue1. */
276 pResult->s.Lo = (uint32_t)uLoValue1 * uLoValue2;
277
278 uTmp.u = (uint32_t)uHiValue1 * uLoValue2;
279 pResult->Words.w3 = 0;
280 pResult->Words.w2 = uTmp.Words.w1;
281 pResult->Words.w1 += uTmp.Words.w0;
282 if (pResult->Words.w1 < uTmp.Words.w0)
283 if (pResult->Words.w2++ == UINT16_MAX)
284 pResult->Words.w3++;
285
286 /* Multiply uLoValue1 and uHiValue1 by uHiValue2. */
287 uTmp.u = (uint32_t)uLoValue1 * uHiValue2;
288 pResult->Words.w1 += uTmp.Words.w0;
289 if (pResult->Words.w1 < uTmp.Words.w0)
290 if (pResult->Words.w2++ == UINT16_MAX)
291 pResult->Words.w3++;
292
293 pResult->Words.w2 += uTmp.Words.w1;
294 if (pResult->Words.w2 < uTmp.Words.w1)
295 pResult->Words.w3++;
296
297 pResult->s.Hi += (uint32_t)uHiValue1 * uHiValue2;
298 return pResult;
299}
300
301
302DECLINLINE(PRTUINT64U) RTUInt64DivRem(PRTUINT64U pQuotient, PRTUINT64U pRemainder, PCRTUINT64U pValue1, PCRTUINT64U pValue2);
303
304/**
305 * Divides a 64-bit unsigned integer value by another.
306 *
307 * @returns pResult
308 * @param pResult The result variable.
309 * @param pValue1 The dividend value.
310 * @param pValue2 The divisor value.
311 */
312DECLINLINE(PRTUINT64U) RTUInt64Div(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
313{
314 RTUINT64U Ignored;
315 return RTUInt64DivRem(pResult, &Ignored, pValue1, pValue2);
316}
317
318
319/**
320 * Divides a 64-bit unsigned integer value by another, returning the remainder.
321 *
322 * @returns pResult
323 * @param pResult The result variable (remainder).
324 * @param pValue1 The dividend value.
325 * @param pValue2 The divisor value.
326 */
327DECLINLINE(PRTUINT64U) RTUInt64Mod(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
328{
329 RTUINT64U Ignored;
330 RTUInt64DivRem(&Ignored, pResult, pValue1, pValue2);
331 return pResult;
332}
333
334
335/**
336 * Bitwise AND of two 64-bit unsigned integer values.
337 *
338 * @returns pResult
339 * @param pResult The result variable.
340 * @param pValue1 The first value.
341 * @param pValue2 The second value.
342 */
343DECLINLINE(PRTUINT64U) RTUInt64And(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
344{
345 pResult->s.Hi = pValue1->s.Hi & pValue2->s.Hi;
346 pResult->s.Lo = pValue1->s.Lo & pValue2->s.Lo;
347 return pResult;
348}
349
350
351/**
352 * Bitwise OR of two 64-bit unsigned integer values.
353 *
354 * @returns pResult
355 * @param pResult The result variable.
356 * @param pValue1 The first value.
357 * @param pValue2 The second value.
358 */
359DECLINLINE(PRTUINT64U) RTUInt64Or( PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
360{
361 pResult->s.Hi = pValue1->s.Hi | pValue2->s.Hi;
362 pResult->s.Lo = pValue1->s.Lo | pValue2->s.Lo;
363 return pResult;
364}
365
366
367/**
368 * Bitwise XOR of two 64-bit unsigned integer values.
369 *
370 * @returns pResult
371 * @param pResult The result variable.
372 * @param pValue1 The first value.
373 * @param pValue2 The second value.
374 */
375DECLINLINE(PRTUINT64U) RTUInt64Xor(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
376{
377 pResult->s.Hi = pValue1->s.Hi ^ pValue2->s.Hi;
378 pResult->s.Lo = pValue1->s.Lo ^ pValue2->s.Lo;
379 return pResult;
380}
381
382
383/**
384 * Shifts a 64-bit unsigned integer value @a cBits to the left.
385 *
386 * @returns pResult
387 * @param pResult The result variable.
388 * @param pValue The value to shift.
389 * @param cBits The number of bits to shift it.
390 */
391DECLINLINE(PRTUINT64U) RTUInt64ShiftLeft(PRTUINT64U pResult, PCRTUINT64U pValue, int cBits)
392{
393 cBits &= 63;
394 if (cBits < 32)
395 {
396 pResult->s.Lo = pValue->s.Lo << cBits;
397 pResult->s.Hi = (pValue->s.Hi << cBits) | (pValue->s.Lo >> (32 - cBits));
398 }
399 else
400 {
401 pResult->s.Lo = 0;
402 pResult->s.Hi = pValue->s.Lo << (cBits - 32);
403 }
404 return pResult;
405}
406
407
408/**
409 * Shifts a 64-bit unsigned integer value @a cBits to the right.
410 *
411 * @returns pResult
412 * @param pResult The result variable.
413 * @param pValue The value to shift.
414 * @param cBits The number of bits to shift it.
415 */
416DECLINLINE(PRTUINT64U) RTUInt64ShiftRight(PRTUINT64U pResult, PCRTUINT64U pValue, int cBits)
417{
418 cBits &= 63;
419 if (cBits < 32)
420 {
421 pResult->s.Hi = pValue->s.Hi >> cBits;
422 pResult->s.Lo = (pValue->s.Lo >> cBits) | (pValue->s.Hi << (32 - cBits));
423 }
424 else
425 {
426 pResult->s.Hi = 0;
427 pResult->s.Lo = pValue->s.Hi >> (cBits - 32);
428 }
429 return pResult;
430}
431
432
433/**
434 * Boolean not (result 0 or 1).
435 *
436 * @returns pResult.
437 * @param pResult The result variable.
438 * @param pValue The value.
439 */
440DECLINLINE(PRTUINT64U) RTUInt64BooleanNot(PRTUINT64U pResult, PCRTUINT64U pValue)
441{
442 pResult->s.Lo = pValue->s.Lo || pValue->s.Hi ? 0 : 1;
443 pResult->s.Hi = 0;
444 return pResult;
445}
446
447
448/**
449 * Bitwise not (flips each bit of the 64 bits).
450 *
451 * @returns pResult.
452 * @param pResult The result variable.
453 * @param pValue The value.
454 */
455DECLINLINE(PRTUINT64U) RTUInt64BitwiseNot(PRTUINT64U pResult, PCRTUINT64U pValue)
456{
457 pResult->s.Hi = ~pValue->s.Hi;
458 pResult->s.Lo = ~pValue->s.Lo;
459 return pResult;
460}
461
462
463/**
464 * Assigns one 64-bit unsigned integer value to another.
465 *
466 * @returns pResult
467 * @param pResult The result variable.
468 * @param pValue The value to assign.
469 */
470DECLINLINE(PRTUINT64U) RTUInt64Assign(PRTUINT64U pResult, PCRTUINT64U pValue)
471{
472#if ARCH_BITS >= 32
473 pResult->s.Hi = pValue->s.Hi;
474 pResult->s.Lo = pValue->s.Lo;
475#else
476 pResult->Words.w0 = pValue->Words.w0;
477 pResult->Words.w1 = pValue->Words.w1;
478 pResult->Words.w2 = pValue->Words.w2;
479 pResult->Words.w3 = pValue->Words.w3;
480#endif
481 return pResult;
482}
483
484
485/**
486 * Assigns a boolean value to 64-bit unsigned integer.
487 *
488 * @returns pValueResult
489 * @param pValueResult The result variable.
490 * @param fValue The boolean value.
491 */
492DECLINLINE(PRTUINT64U) RTUInt64AssignBoolean(PRTUINT64U pValueResult, bool fValue)
493{
494#if ARCH_BITS >= 32
495 pValueResult->s.Lo = fValue;
496 pValueResult->s.Hi = 0;
497#else
498 pValueResult->Words.w0 = fValue;
499 pValueResult->Words.w1 = 0;
500 pValueResult->Words.w2 = 0;
501 pValueResult->Words.w3 = 0;
502#endif
503 return pValueResult;
504}
505
506
507/**
508 * Assigns a 8-bit unsigned integer value to 64-bit unsigned integer.
509 *
510 * @returns pValueResult
511 * @param pValueResult The result variable.
512 * @param u8Value The 8-bit unsigned integer value.
513 */
514DECLINLINE(PRTUINT64U) RTUInt64AssignU8(PRTUINT64U pValueResult, uint8_t u8Value)
515{
516#if ARCH_BITS >= 32
517 pValueResult->s.Lo = u8Value;
518 pValueResult->s.Hi = 0;
519#else
520 pValueResult->Words.w0 = u8Value;
521 pValueResult->Words.w1 = 0;
522 pValueResult->Words.w2 = 0;
523 pValueResult->Words.w3 = 0;
524#endif
525 return pValueResult;
526}
527
528
529/**
530 * Assigns a 16-bit unsigned integer value to 64-bit unsigned integer.
531 *
532 * @returns pValueResult
533 * @param pValueResult The result variable.
534 * @param u16Value The 16-bit unsigned integer value.
535 */
536DECLINLINE(PRTUINT64U) RTUInt64AssignU16(PRTUINT64U pValueResult, uint16_t u16Value)
537{
538#if ARCH_BITS >= 32
539 pValueResult->s.Lo = u16Value;
540 pValueResult->s.Hi = 0;
541#else
542 pValueResult->Words.w0 = u16Value;
543 pValueResult->Words.w1 = 0;
544 pValueResult->Words.w2 = 0;
545 pValueResult->Words.w3 = 0;
546#endif
547 return pValueResult;
548}
549
550
551/**
552 * Assigns a 32-bit unsigned integer value to 64-bit unsigned integer.
553 *
554 * @returns pValueResult
555 * @param pValueResult The result variable.
556 * @param u32Value The 32-bit unsigned integer value.
557 */
558DECLINLINE(PRTUINT64U) RTUInt64AssignU32(PRTUINT64U pValueResult, uint32_t u32Value)
559{
560#if ARCH_BITS >= 32
561 pValueResult->s.Lo = u32Value;
562 pValueResult->s.Hi = 0;
563#else
564 pValueResult->Words.w0 = (uint16_t)u32Value;
565 pValueResult->Words.w1 = u32Value >> 16;
566 pValueResult->Words.w2 = 0;
567 pValueResult->Words.w3 = 0;
568#endif
569 return pValueResult;
570}
571
572
573/**
574 * Adds two 64-bit unsigned integer values, storing the result in the first.
575 *
576 * @returns pValue1Result.
577 * @param pValue1Result The first value and result.
578 * @param pValue2 The second value.
579 */
580DECLINLINE(PRTUINT64U) RTUInt64AssignAdd(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
581{
582 uint32_t const uTmp = pValue1Result->s.Lo;
583 pValue1Result->s.Lo += pValue2->s.Lo;
584 if (pValue1Result->s.Lo < uTmp)
585 pValue1Result->s.Hi++;
586 pValue1Result->s.Hi += pValue2->s.Hi;
587 return pValue1Result;
588}
589
590
591/**
592 * Subtracts two 64-bit unsigned integer values, storing the result in the
593 * first.
594 *
595 * @returns pValue1Result.
596 * @param pValue1Result The minuend value and result.
597 * @param pValue2 The subtrahend value.
598 */
599DECLINLINE(PRTUINT64U) RTUInt64AssignSub(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
600{
601 uint32_t const uTmp = pValue1Result->s.Lo;
602 pValue1Result->s.Lo -= pValue2->s.Lo;
603 if (pValue1Result->s.Lo > uTmp)
604 pValue1Result->s.Hi--;
605 pValue1Result->s.Hi -= pValue2->s.Hi;
606 return pValue1Result;
607}
608
609
610/**
611 * Multiplies two 64-bit unsigned integer values, storing the result in the
612 * first.
613 *
614 * @returns pValue1Result.
615 * @param pValue1Result The first value and result.
616 * @param pValue2 The second value.
617 */
618DECLINLINE(PRTUINT64U) RTUInt64AssignMul(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
619{
620 RTUINT64U Result;
621 RTUInt64Mul(&Result, pValue1Result, pValue2);
622 *pValue1Result = Result;
623 return pValue1Result;
624}
625
626
627/**
628 * Divides a 64-bit unsigned integer value by another, storing the result in
629 * the first.
630 *
631 * @returns pValue1Result.
632 * @param pValue1Result The dividend value and result.
633 * @param pValue2 The divisor value.
634 */
635DECLINLINE(PRTUINT64U) RTUInt64AssignDiv(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
636{
637 RTUINT64U Result;
638 RTUINT64U Ignored;
639 RTUInt64DivRem(&Result, &Ignored, pValue1Result, pValue2);
640 *pValue1Result = Result;
641 return pValue1Result;
642}
643
644
645/**
646 * Divides a 64-bit unsigned integer value by another, storing the remainder in
647 * the first.
648 *
649 * @returns pValue1Result.
650 * @param pValue1Result The dividend value and result (remainder).
651 * @param pValue2 The divisor value.
652 */
653DECLINLINE(PRTUINT64U) RTUInt64AssignMod(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
654{
655 RTUINT64U Ignored;
656 RTUINT64U Result;
657 RTUInt64DivRem(&Ignored, &Result, pValue1Result, pValue2);
658 *pValue1Result = Result;
659 return pValue1Result;
660}
661
662
663/**
664 * Performs a bitwise AND of two 64-bit unsigned integer values and assigned
665 * the result to the first one.
666 *
667 * @returns pValue1Result.
668 * @param pValue1Result The first value and result.
669 * @param pValue2 The second value.
670 */
671DECLINLINE(PRTUINT64U) RTUInt64AssignAnd(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
672{
673#if ARCH_BITS >= 32
674 pValue1Result->s.Hi &= pValue2->s.Hi;
675 pValue1Result->s.Lo &= pValue2->s.Lo;
676#else
677 pValue1Result->Words.w0 &= pValue2->Words.w0;
678 pValue1Result->Words.w1 &= pValue2->Words.w1;
679 pValue1Result->Words.w2 &= pValue2->Words.w2;
680 pValue1Result->Words.w3 &= pValue2->Words.w3;
681#endif
682 return pValue1Result;
683}
684
685
686/**
687 * Performs a bitwise AND of a 64-bit unsigned integer value and a mask made
688 * up of the first N bits, assigning the result to the the 64-bit value.
689 *
690 * @returns pValueResult.
691 * @param pValueResult The value and result.
692 * @param cBits The number of bits to AND (counting from the first
693 * bit).
694 */
695DECLINLINE(PRTUINT64U) RTUInt64AssignAndNFirstBits(PRTUINT64U pValueResult, unsigned cBits)
696{
697 if (cBits <= 32)
698 {
699 if (cBits != 32)
700 pValueResult->s.Lo &= (RT_BIT_32(cBits) - 1);
701 pValueResult->s.Hi = 0;
702 }
703 else if (cBits < 64)
704 pValueResult->s.Hi &= (RT_BIT_32(cBits - 32) - 1);
705 return pValueResult;
706}
707
708
709/**
710 * Performs a bitwise OR of two 64-bit unsigned integer values and assigned
711 * the result to the first one.
712 *
713 * @returns pValue1Result.
714 * @param pValue1Result The first value and result.
715 * @param pValue2 The second value.
716 */
717DECLINLINE(PRTUINT64U) RTUInt64AssignOr(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
718{
719#if ARCH_BITS >= 32
720 pValue1Result->s.Hi |= pValue2->s.Hi;
721 pValue1Result->s.Lo |= pValue2->s.Lo;
722#else
723 pValue1Result->Words.w0 |= pValue2->Words.w0;
724 pValue1Result->Words.w1 |= pValue2->Words.w1;
725 pValue1Result->Words.w2 |= pValue2->Words.w2;
726 pValue1Result->Words.w3 |= pValue2->Words.w3;
727#endif
728 return pValue1Result;
729}
730
731
732/**
733 * ORs in a bit and assign the result to the input value.
734 *
735 * @returns pValue1Result.
736 * @param pValue1Result The first value and result.
737 * @param iBit The bit to set (0 based).
738 */
739DECLINLINE(PRTUINT64U) RTUInt64AssignOrBit(PRTUINT64U pValue1Result, unsigned iBit)
740{
741#if ARCH_BITS >= 32
742 if (iBit >= 32)
743 pValue1Result->s.Hi |= RT_BIT_32(iBit - 32);
744 else
745 pValue1Result->s.Lo |= RT_BIT_32(iBit);
746#else
747 if (iBit >= 32)
748 {
749 if (iBit >= 48)
750 pValue1Result->Words.w3 |= UINT16_C(1) << (iBit - 48);
751 else
752 pValue1Result->Words.w2 |= UINT16_C(1) << (iBit - 32);
753 }
754 else
755 {
756 if (iBit >= 16)
757 pValue1Result->Words.w1 |= UINT16_C(1) << (iBit - 16);
758 else
759 pValue1Result->Words.w0 |= UINT16_C(1) << (iBit);
760 }
761#endif
762 return pValue1Result;
763}
764
765
766
767/**
768 * Performs a bitwise XOR of two 64-bit unsigned integer values and assigned
769 * the result to the first one.
770 *
771 * @returns pValue1Result.
772 * @param pValue1Result The first value and result.
773 * @param pValue2 The second value.
774 */
775DECLINLINE(PRTUINT64U) RTUInt64AssignXor(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
776{
777#if ARCH_BITS >= 32
778 pValue1Result->s.Hi ^= pValue2->s.Hi;
779 pValue1Result->s.Lo ^= pValue2->s.Lo;
780#else
781 pValue1Result->Words.w0 ^= pValue2->Words.w0;
782 pValue1Result->Words.w1 ^= pValue2->Words.w1;
783 pValue1Result->Words.w2 ^= pValue2->Words.w2;
784 pValue1Result->Words.w3 ^= pValue2->Words.w3;
785#endif
786 return pValue1Result;
787}
788
789
790/**
791 * Performs a bitwise left shift on a 64-bit unsigned integer value, assigning
792 * the result to it.
793 *
794 * @returns pValueResult.
795 * @param pValueResult The first value and result.
796 * @param cBits The number of bits to shift.
797 */
798DECLINLINE(PRTUINT64U) RTUInt64AssignShiftLeft(PRTUINT64U pValueResult, int cBits)
799{
800 RTUINT64U const InVal = *pValueResult;
801 if (cBits > 0)
802 {
803 /* (left shift) */
804 cBits &= 31;
805 if (cBits >= 32)
806 {
807 pValueResult->s.Lo = 0;
808 pValueResult->s.Hi = InVal.s.Lo << (cBits - 32);
809 }
810 else
811 {
812 pValueResult->s.Hi = InVal.s.Hi << cBits;
813 pValueResult->s.Hi |= InVal.s.Lo >> (32 - cBits);
814 pValueResult->s.Lo = InVal.s.Lo << cBits;
815 }
816 }
817 else if (cBits < 0)
818 {
819 /* (right shift) */
820 cBits = -cBits;
821 cBits &= 31;
822 if (cBits >= 32)
823 {
824 pValueResult->s.Hi = 0;
825 pValueResult->s.Lo = InVal.s.Hi >> (cBits - 32);
826 }
827 else
828 {
829 pValueResult->s.Lo = InVal.s.Lo >> cBits;
830 pValueResult->s.Lo |= InVal.s.Hi << (32 - cBits);
831 pValueResult->s.Hi = InVal.s.Hi >> cBits;
832 }
833 }
834 return pValueResult;
835}
836
837
838/**
839 * Performs a bitwise left shift on a 64-bit unsigned integer value, assigning
840 * the result to it.
841 *
842 * @returns pValueResult.
843 * @param pValueResult The first value and result.
844 * @param cBits The number of bits to shift.
845 */
846DECLINLINE(PRTUINT64U) RTUInt64AssignShiftRight(PRTUINT64U pValueResult, int cBits)
847{
848 return RTUInt64AssignShiftLeft(pValueResult, -cBits);
849}
850
851
852/**
853 * Performs a bitwise NOT on a 64-bit unsigned integer value, assigning the
854 * result to it.
855 *
856 * @returns pValueResult
857 * @param pValueResult The value and result.
858 */
859DECLINLINE(PRTUINT64U) RTUInt64AssignBitwiseNot(PRTUINT64U pValueResult)
860{
861#if ARCH_BITS >= 32
862 pValueResult->s.Hi = ~pValueResult->s.Hi;
863 pValueResult->s.Lo = ~pValueResult->s.Lo;
864#else
865 pValueResult->Words.w0 = ~pValueResult->Words.w0;
866 pValueResult->Words.w1 = ~pValueResult->Words.w1;
867 pValueResult->Words.w2 = ~pValueResult->Words.w2;
868 pValueResult->Words.w3 = ~pValueResult->Words.w3;
869#endif
870 return pValueResult;
871}
872
873
874/**
875 * Performs a boolean NOT on a 64-bit unsigned integer value, assigning the
876 * result to it.
877 *
878 * @returns pValueResult
879 * @param pValueResult The value and result.
880 */
881DECLINLINE(PRTUINT64U) RTUInt64AssignBooleanNot(PRTUINT64U pValueResult)
882{
883 return RTUInt64AssignBoolean(pValueResult, RTUInt64IsZero(pValueResult));
884}
885
886
887/**
888 * Compares two 64-bit unsigned integer values.
889 *
890 * @retval 0 if equal.
891 * @retval -1 if the first value is smaller than the second.
892 * @retval 1 if the first value is larger than the second.
893 *
894 * @param pValue1 The first value.
895 * @param pValue2 The second value.
896 */
897DECLINLINE(int) RTUInt64Compare(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
898{
899#if ARCH_BITS >= 32
900 if (pValue1->s.Hi != pValue2->s.Hi)
901 return pValue1->s.Hi > pValue2->s.Hi ? 1 : -1;
902 if (pValue1->s.Lo != pValue2->s.Lo)
903 return pValue1->s.Lo > pValue2->s.Lo ? 1 : -1;
904 return 0;
905#else
906 if (pValue1->Words.w3 != pValue2->Words.w3)
907 return pValue1->Words.w3 > pValue2->Words.w3 ? 1 : -1;
908 if (pValue1->Words.w2 != pValue2->Words.w2)
909 return pValue1->Words.w2 > pValue2->Words.w2 ? 1 : -1;
910 if (pValue1->Words.w1 != pValue2->Words.w1)
911 return pValue1->Words.w1 > pValue2->Words.w1 ? 1 : -1;
912 if (pValue1->Words.w0 != pValue2->Words.w0)
913 return pValue1->Words.w0 > pValue2->Words.w0 ? 1 : -1;
914 return 0;
915#endif
916}
917
918
919/**
920 * Tests if a 64-bit unsigned integer value is smaller than another.
921 *
922 * @returns true if the first value is smaller, false if not.
923 * @param pValue1 The first value.
924 * @param pValue2 The second value.
925 */
926DECLINLINE(bool) RTUInt64IsSmaller(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
927{
928#if ARCH_BITS >= 32
929 return pValue1->s.Hi < pValue2->s.Hi
930 || ( pValue1->s.Hi == pValue2->s.Hi
931 && pValue1->s.Lo < pValue2->s.Lo);
932#else
933 return pValue1->Words.w3 < pValue2->Words.w3
934 || ( pValue1->Words.w3 == pValue2->Words.w3
935 && ( pValue1->Words.w2 < pValue2->Words.w2
936 || ( pValue1->Words.w2 == pValue2->Words.w2
937 && ( pValue1->Words.w1 < pValue2->Words.w1
938 || ( pValue1->Words.w1 == pValue2->Words.w1
939 && pValue1->Words.w0 < pValue2->Words.w0)))));
940#endif
941}
942
943
944/**
945 * Tests if a 32-bit unsigned integer value is larger than another.
946 *
947 * @returns true if the first value is larger, false if not.
948 * @param pValue1 The first value.
949 * @param pValue2 The second value.
950 */
951DECLINLINE(bool) RTUInt64IsLarger(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
952{
953#if ARCH_BITS >= 32
954 return pValue1->s.Hi > pValue2->s.Hi
955 || ( pValue1->s.Hi == pValue2->s.Hi
956 && pValue1->s.Lo > pValue2->s.Lo);
957#else
958 return pValue1->Words.w3 > pValue2->Words.w3
959 || ( pValue1->Words.w3 == pValue2->Words.w3
960 && ( pValue1->Words.w2 > pValue2->Words.w2
961 || ( pValue1->Words.w2 == pValue2->Words.w2
962 && ( pValue1->Words.w1 > pValue2->Words.w1
963 || ( pValue1->Words.w1 == pValue2->Words.w1
964 && pValue1->Words.w0 > pValue2->Words.w0)))));
965#endif
966}
967
968
969/**
970 * Tests if a 64-bit unsigned integer value is larger or equal than another.
971 *
972 * @returns true if the first value is larger or equal, false if not.
973 * @param pValue1 The first value.
974 * @param pValue2 The second value.
975 */
976DECLINLINE(bool) RTUInt64IsLargerOrEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
977{
978#if ARCH_BITS >= 32
979 return pValue1->s.Hi > pValue2->s.Hi
980 || ( pValue1->s.Hi == pValue2->s.Hi
981 && pValue1->s.Lo >= pValue2->s.Lo);
982#else
983 return pValue1->Words.w3 > pValue2->Words.w3
984 || ( pValue1->Words.w3 == pValue2->Words.w3
985 && ( pValue1->Words.w2 > pValue2->Words.w2
986 || ( pValue1->Words.w2 == pValue2->Words.w2
987 && ( pValue1->Words.w1 > pValue2->Words.w1
988 || ( pValue1->Words.w1 == pValue2->Words.w1
989 && pValue1->Words.w0 >= pValue2->Words.w0)))));
990#endif
991}
992
993
994/**
995 * Tests if two 64-bit unsigned integer values not equal.
996 *
997 * @returns true if equal, false if not equal.
998 * @param pValue1 The first value.
999 * @param pValue2 The second value.
1000 */
1001DECLINLINE(bool) RTUInt64IsEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1002{
1003#if ARCH_BITS >= 32
1004 return pValue1->s.Hi == pValue2->s.Hi
1005 && pValue1->s.Lo == pValue2->s.Lo;
1006#else
1007 return pValue1->Words.w0 == pValue2->Words.w0
1008 && pValue1->Words.w1 == pValue2->Words.w1
1009 && pValue1->Words.w2 == pValue2->Words.w2
1010 && pValue1->Words.w3 == pValue2->Words.w3;
1011#endif
1012}
1013
1014
1015/**
1016 * Tests if two 64-bit unsigned integer values are not equal.
1017 *
1018 * @returns true if not equal, false if equal.
1019 * @param pValue1 The first value.
1020 * @param pValue2 The second value.
1021 */
1022DECLINLINE(bool) RTUInt64IsNotEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1023{
1024 return !RTUInt64IsEqual(pValue1, pValue2);
1025}
1026
1027
1028/**
1029 * Sets a bit in a 64-bit unsigned integer type.
1030 *
1031 * @returns pValueResult.
1032 * @param pValueResult The input and output value.
1033 * @param iBit The bit to set.
1034 */
1035DECLINLINE(PRTUINT64U) RTUInt64BitSet(PRTUINT64U pValueResult, unsigned iBit)
1036{
1037 if (iBit < 32)
1038 {
1039#if ARCH_BITS >= 32
1040 pValueResult->s.Lo |= RT_BIT_32(iBit);
1041#else
1042 if (iBit < 16)
1043 pValueResult->Words.w0 |= UINT16_C(1) << iBit;
1044 else
1045 pValueResult->Words.w1 |= UINT16_C(1) << (iBit - 32);
1046#endif
1047 }
1048 else if (iBit < 64)
1049 {
1050#if ARCH_BITS >= 32
1051 pValueResult->s.Hi |= RT_BIT_32(iBit - 32);
1052#else
1053 if (iBit < 48)
1054 pValueResult->Words.w2 |= UINT16_C(1) << (iBit - 64);
1055 else
1056 pValueResult->Words.w3 |= UINT16_C(1) << (iBit - 96);
1057#endif
1058 }
1059 return pValueResult;
1060}
1061
1062
1063/**
1064 * Sets a bit in a 64-bit unsigned integer type.
1065 *
1066 * @returns pValueResult.
1067 * @param pValueResult The input and output value.
1068 * @param iBit The bit to set.
1069 */
1070DECLINLINE(PRTUINT64U) RTUInt64BitClear(PRTUINT64U pValueResult, unsigned iBit)
1071{
1072 if (iBit < 32)
1073 {
1074#if ARCH_BITS >= 32
1075 pValueResult->s.Lo &= ~RT_BIT_32(iBit);
1076#else
1077 if (iBit < 48)
1078 pValueResult->Words.w0 &= ~(UINT16_C(1) << (iBit));
1079 else
1080 pValueResult->Words.w1 &= ~(UINT16_C(1) << (iBit - 32));
1081#endif
1082 }
1083 else if (iBit < 64)
1084 {
1085#if ARCH_BITS >= 32
1086 pValueResult->s.Hi &= ~RT_BIT_32(iBit - 32);
1087#else
1088 if (iBit < 48)
1089 pValueResult->Words.w2 &= ~(UINT16_C(1) << (iBit - 64));
1090 else
1091 pValueResult->Words.w3 &= ~(UINT16_C(1) << (iBit - 96));
1092#endif
1093 }
1094 return pValueResult;
1095}
1096
1097
1098/**
1099 * Tests if a bit in a 64-bit unsigned integer value is set.
1100 *
1101 * @returns pValueResult.
1102 * @param pValueResult The input and output value.
1103 * @param iBit The bit to test.
1104 */
1105DECLINLINE(bool) RTUInt64BitTest(PRTUINT64U pValueResult, unsigned iBit)
1106{
1107 bool fRc;
1108 if (iBit < 32)
1109 {
1110#if ARCH_BITS >= 32
1111 fRc = RT_BOOL(pValueResult->s.Lo & RT_BIT_32(iBit));
1112#else
1113 if (iBit < 16)
1114 fRc = RT_BOOL(pValueResult->Words.w0 & (UINT16_C(1) << (iBit)));
1115 else
1116 fRc = RT_BOOL(pValueResult->Words.w1 & (UINT16_C(1) << (iBit - 16)));
1117#endif
1118 }
1119 else if (iBit < 64)
1120 {
1121#if ARCH_BITS >= 32
1122 fRc = RT_BOOL(pValueResult->s.Hi & RT_BIT_32(iBit - 32));
1123#else
1124 if (iBit < 48)
1125 fRc = RT_BOOL(pValueResult->Words.w2 & (UINT16_C(1) << (iBit - 32)));
1126 else
1127 fRc = RT_BOOL(pValueResult->Words.w3 & (UINT16_C(1) << (iBit - 48)));
1128#endif
1129 }
1130 else
1131 fRc = false;
1132 return fRc;
1133}
1134
1135
1136/**
1137 * Set a range of bits a 64-bit unsigned integer value.
1138 *
1139 * @returns pValueResult.
1140 * @param pValueResult The input and output value.
1141 * @param iFirstBit The first bit to test.
1142 * @param cBits The number of bits to set.
1143 */
1144DECLINLINE(PRTUINT64U) RTUInt64BitSetRange(PRTUINT64U pValueResult, unsigned iFirstBit, unsigned cBits)
1145{
1146 /* bounds check & fix. */
1147 if (iFirstBit < 64)
1148 {
1149 if (iFirstBit + cBits > 64)
1150 cBits = 64 - iFirstBit;
1151
1152#if ARCH_BITS >= 32
1153 if (iFirstBit + cBits < 32)
1154 pValueResult->s.Lo |= (RT_BIT_32(cBits) - 1) << iFirstBit;
1155 else if (iFirstBit + cBits < 64 && iFirstBit >= 32)
1156 pValueResult->s.Hi |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 32);
1157 else
1158#else
1159 if (iFirstBit + cBits < 16)
1160 pValueResult->Words.w0 |= ((UINT16_C(1) << cBits) - 1) << iFirstBit;
1161 else if (iFirstBit + cBits < 32 && iFirstBit >= 16)
1162 pValueResult->Words.w1 |= ((UINT16_C(1) << cBits) - 1) << (iFirstBit - 16);
1163 else if (iFirstBit + cBits < 48 && iFirstBit >= 32)
1164 pValueResult->Words.w2 |= ((UINT16_C(1) << cBits) - 1) << (iFirstBit - 32);
1165 else if (iFirstBit + cBits < 64 && iFirstBit >= 48)
1166 pValueResult->Words.w3 |= ((UINT16_C(1) << cBits) - 1) << (iFirstBit - 48);
1167 else
1168#endif
1169 while (cBits-- > 0)
1170 RTUInt64BitSet(pValueResult, iFirstBit++);
1171 }
1172 return pValueResult;
1173}
1174
1175
1176/**
1177 * Test if all the bits of a 64-bit unsigned integer value are set.
1178 *
1179 * @returns true if they are, false if they aren't.
1180 * @param pValue The input and output value.
1181 */
1182DECLINLINE(bool) RTUInt64BitAreAllSet(PRTUINT64U pValue)
1183{
1184#if ARCH_BITS >= 32
1185 return pValue->s.Hi == UINT32_MAX
1186 && pValue->s.Lo == UINT32_MAX;
1187#else
1188 return pValue->Words.w0 == UINT16_MAX
1189 && pValue->Words.w1 == UINT16_MAX
1190 && pValue->Words.w2 == UINT16_MAX
1191 && pValue->Words.w3 == UINT16_MAX;
1192#endif
1193}
1194
1195
1196/**
1197 * Test if all the bits of a 64-bit unsigned integer value are clear.
1198 *
1199 * @returns true if they are, false if they aren't.
1200 * @param pValue The input and output value.
1201 */
1202DECLINLINE(bool) RTUInt64BitAreAllClear(PRTUINT64U pValue)
1203{
1204 return RTUInt64IsZero(pValue);
1205}
1206
1207
1208DECLINLINE(unsigned) RTUInt64BitCount(PCRTUINT64U pValue)
1209{
1210 unsigned cBits;
1211 if (pValue->s.Hi != 0)
1212 {
1213#if ARCH_BITS >= 32
1214 cBits = 32 + ASMBitLastSetU32(pValue->s.Hi);
1215#else
1216 if (pValue->Words.w3)
1217 cBits = 48 + ASMBitLastSetU16(pValue->Words.w3);
1218 else
1219 cBits = 32 + ASMBitLastSetU16(pValue->Words.w2);
1220#endif
1221 }
1222 else
1223 {
1224#if ARCH_BITS >= 32
1225 cBits = ASMBitLastSetU32(pValue->s.Lo);
1226#else
1227 if (pValue->Words.w1)
1228 cBits = 16 + ASMBitLastSetU16(pValue->Words.w1);
1229 else
1230 cBits = 0 + ASMBitLastSetU16(pValue->Words.w0);
1231#endif
1232 }
1233 return cBits;
1234}
1235
1236
1237/**
1238 * Divides a 64-bit unsigned integer value by another, returning both quotient
1239 * and remainder.
1240 *
1241 * @returns pQuotient, NULL if pValue2 is 0.
1242 * @param pQuotient Where to return the quotient.
1243 * @param pRemainder Where to return the remainder.
1244 * @param pValue1 The dividend value.
1245 * @param pValue2 The divisor value.
1246 */
1247DECLINLINE(PRTUINT64U) RTUInt64DivRem(PRTUINT64U pQuotient, PRTUINT64U pRemainder, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
1248{
1249 int iDiff;
1250
1251 /*
1252 * Sort out all the special cases first.
1253 */
1254 /* Divide by zero or 1? */
1255 if (!pValue2->s.Hi)
1256 {
1257 if (!pValue2->s.Lo)
1258 return NULL;
1259
1260 if (pValue2->s.Lo == 1)
1261 {
1262 RTUInt64SetZero(pRemainder);
1263 *pQuotient = *pValue1;
1264 return pQuotient;
1265 }
1266 /** @todo RTUInt64DivModByU32 */
1267 }
1268
1269 /* Dividend is smaller? */
1270 iDiff = RTUInt64Compare(pValue1, pValue2);
1271 if (iDiff < 0)
1272 {
1273 *pRemainder = *pValue1;
1274 RTUInt64SetZero(pQuotient);
1275 }
1276
1277 /* The values are equal? */
1278 else if (iDiff == 0)
1279 {
1280 RTUInt64SetZero(pRemainder);
1281 RTUInt64AssignU8(pQuotient, 1);
1282 }
1283 else
1284 {
1285 /*
1286 * Prepare.
1287 */
1288 unsigned iBitAdder = RTUInt64BitCount(pValue1) - RTUInt64BitCount(pValue2);
1289 RTUINT64U NormDivisor = *pValue2;
1290 if (iBitAdder)
1291 {
1292 RTUInt64ShiftLeft(&NormDivisor, pValue2, iBitAdder);
1293 if (RTUInt64IsLarger(&NormDivisor, pValue1))
1294 {
1295 RTUInt64AssignShiftRight(&NormDivisor, 1);
1296 iBitAdder--;
1297 }
1298 }
1299 else
1300 NormDivisor = *pValue2;
1301
1302 RTUInt64SetZero(pQuotient);
1303 *pRemainder = *pValue1;
1304
1305 /*
1306 * Do the division.
1307 */
1308 if (RTUInt64IsLargerOrEqual(pRemainder, pValue2))
1309 {
1310 for (;;)
1311 {
1312 if (RTUInt64IsLargerOrEqual(pRemainder, &NormDivisor))
1313 {
1314 RTUInt64AssignSub(pRemainder, &NormDivisor);
1315 RTUInt64AssignOrBit(pQuotient, iBitAdder);
1316 }
1317 if (RTUInt64IsSmaller(pRemainder, pValue2))
1318 break;
1319 RTUInt64AssignShiftRight(&NormDivisor, 1);
1320 iBitAdder--;
1321 }
1322 }
1323 }
1324 return pQuotient;
1325}
1326
1327
1328/** @} */
1329
1330RT_C_DECLS_END
1331
1332#endif /* !IPRT_INCLUDED_uint64_h */
1333
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette