VirtualBox

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

Last change on this file since 98103 was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use