VirtualBox

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

Last change on this file since 68154 was 60485, checked in by vboxsync, 9 years ago

bs3kit: 8086 friendly 32-bit and 64-bit unsigned integer division.

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