VirtualBox

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

Last change on this file since 77807 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.3 KB
RevLine 
[35488]1/** @file
[60482]2 * IPRT - RTUINT64U methods for old 32-bit and 16-bit compilers.
[35488]3 */
4
5/*
[76553]6 * Copyright (C) 2011-2019 Oracle Corporation
[35488]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
[76557]26#ifndef IPRT_INCLUDED_uint64_h
27#define IPRT_INCLUDED_uint64_h
[76507]28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
[35488]31
32#include <iprt/cdefs.h>
33#include <iprt/types.h>
[52335]34#include <iprt/asm.h>
[35488]35
36RT_C_DECLS_BEGIN
37
[60482]38/** @defgroup grp_rt_uint64 RTUInt64 - 64-bit Unsigned Integer Methods for ancient compilers
[35488]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 */
[60482]50DECLINLINE(bool) RTUInt64IsZero(PRTUINT64U pValue)
[35488]51{
[60482]52#if ARCH_BITS >= 32
53 return pValue->s.Lo == 0
54 && pValue->s.Hi == 0;
[35488]55#else
[60482]56 return pValue->Words.w0 == 0
57 && pValue->Words.w1 == 0
58 && pValue->Words.w2 == 0
59 && pValue->Words.w3 == 0;
[35488]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 */
[60482]70DECLINLINE(PRTUINT64U) RTUInt64SetZero(PRTUINT64U pResult)
[35488]71{
[60482]72#if ARCH_BITS >= 32
[35488]73 pResult->s.Hi = 0;
74 pResult->s.Lo = 0;
75#else
[60482]76 pResult->Words.w0 = 0;
77 pResult->Words.w1 = 0;
78 pResult->Words.w2 = 0;
79 pResult->Words.w3 = 0;
[35488]80#endif
81 return pResult;
82}
83
84
85/**
[60482]86 * Set a 32-bit unsigned integer value to the maximum value.
[35488]87 *
88 * @returns pResult
89 * @param pResult The result variable.
90 */
[60482]91DECLINLINE(PRTUINT64U) RTUInt64SetMax(PRTUINT64U pResult)
[35488]92{
[60482]93#if ARCH_BITS >= 32
94 pResult->s.Hi = UINT32_MAX;
95 pResult->s.Lo = UINT32_MAX;
[35488]96#else
[60482]97 pResult->Words.w0 = UINT16_MAX;
98 pResult->Words.w1 = UINT16_MAX;
99 pResult->Words.w2 = UINT16_MAX;
100 pResult->Words.w3 = UINT16_MAX;
[35488]101#endif
102 return pResult;
103}
104
105
106
107
108/**
[60482]109 * Adds two 64-bit unsigned integer values.
[52335]110 *
111 * @returns pResult
112 * @param pResult The result variable.
113 * @param pValue1 The first value.
114 * @param pValue2 The second value.
115 */
[60482]116DECLINLINE(PRTUINT64U) RTUInt64Add(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]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/**
[60482]127 * Adds a 64-bit and a 32-bit unsigned integer values.
[52335]128 *
129 * @returns pResult
130 * @param pResult The result variable.
131 * @param pValue1 The first value.
[60482]132 * @param uValue2 The second value, 32-bit.
[52335]133 */
[60482]134DECLINLINE(PRTUINT64U) RTUInt64AddU32(PRTUINT64U pResult, PCRTUINT64U pValue1, uint32_t uValue2)
[52335]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/**
[60482]145 * Subtracts a 64-bit unsigned integer value from another.
[52335]146 *
147 * @returns pResult
148 * @param pResult The result variable.
149 * @param pValue1 The minuend value.
150 * @param pValue2 The subtrahend value.
151 */
[60482]152DECLINLINE(PRTUINT64U) RTUInt64Sub(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]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/**
[60482]163 * Multiplies two 64-bit unsigned integer values.
[52335]164 *
165 * @returns pResult
166 * @param pResult The result variable.
167 * @param pValue1 The first value.
168 * @param pValue2 The second value.
169 */
[60482]170DECLINLINE(PRTUINT64U) RTUInt64Mul(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]171{
[60482]172 RTUINT32U uTmp;
[52335]173
[60482]174 /* multiply all words in v1 by v2.w0. */
175 pResult->s.Lo = (uint32_t)pValue1->Words.w0 * pValue2->Words.w0;
[52335]176
[60482]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++;
[52335]184
[60482]185 pResult->s.Hi += (uint32_t)pValue1->Words.w2 * pValue2->Words.w0;
186 pResult->Words.w3 += pValue1->Words.w3 * pValue2->Words.w0;
[52335]187
[60482]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++;
[52335]194
[60482]195 pResult->Words.w2 += uTmp.Words.w1;
196 if (pResult->Words.w2 < uTmp.Words.w1)
197 pResult->Words.w3++;
[52335]198
[60482]199 pResult->s.Hi += (uint32_t)pValue1->Words.w1 * pValue2->Words.w1;
200 pResult->Words.w3 += pValue1->Words.w2 * pValue2->Words.w1;
[52335]201
[60482]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;
[52335]205
[60482]206 /* multiply w0 in v1 by v2.w3. */
207 pResult->Words.w3 += pValue1->Words.w0 * pValue2->Words.w3;
[52335]208
209 return pResult;
210}
211
212
213/**
[60482]214 * Multiplies an 64-bit unsigned integer by a 32-bit unsigned integer value.
[52335]215 *
216 * @returns pResult
217 * @param pResult The result variable.
218 * @param pValue1 The first value.
[60482]219 * @param uValue2 The second value, 32-bit.
[52335]220 */
[60482]221DECLINLINE(PRTUINT64U) RTUInt64MulByU32(PRTUINT64U pResult, PCRTUINT64U pValue1, uint32_t uValue2)
[52335]222{
[60482]223 uint16_t const uLoValue2 = (uint16_t)uValue2;
224 uint16_t const uHiValue2 = (uint16_t)(uValue2 >> 16);
225 RTUINT32U uTmp;
[52335]226
[60482]227 /* multiply all words in v1 by uLoValue1. */
228 pResult->s.Lo = (uint32_t)pValue1->Words.w0 * uLoValue2;
[52335]229
[60482]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++;
[52335]237
[60482]238 pResult->s.Hi += (uint32_t)pValue1->Words.w2 * uLoValue2;
239 pResult->Words.w3 += pValue1->Words.w3 * uLoValue2;
[52335]240
[60482]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++;
[52335]247
[60482]248 pResult->Words.w2 += uTmp.Words.w1;
249 if (pResult->Words.w2 < uTmp.Words.w1)
250 pResult->Words.w3++;
[52335]251
[60482]252 pResult->s.Hi += (uint32_t)pValue1->Words.w1 * uHiValue2;
253 pResult->Words.w3 += pValue1->Words.w2 * uHiValue2;
[52335]254
255 return pResult;
256}
257
258
259/**
[60482]260 * Multiplies two 32-bit unsigned integer values with 64-bit precision.
[52335]261 *
262 * @returns pResult
263 * @param pResult The result variable.
[60482]264 * @param uValue1 The first value. 32-bit.
265 * @param uValue2 The second value, 32-bit.
[52335]266 */
[60482]267DECLINLINE(PRTUINT64U) RTUInt64MulU32ByU32(PRTUINT64U pResult, uint32_t uValue1, uint32_t uValue2)
[52335]268{
[60482]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;
[52335]274
275 /* Multiply uLoValue1 and uHiValue1 by uLoValue1. */
[60482]276 pResult->s.Lo = (uint32_t)uLoValue1 * uLoValue2;
[52335]277
[60482]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++;
[52335]285
286 /* Multiply uLoValue1 and uHiValue1 by uHiValue2. */
[60482]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++;
[52335]292
[60482]293 pResult->Words.w2 += uTmp.Words.w1;
294 if (pResult->Words.w2 < uTmp.Words.w1)
295 pResult->Words.w3++;
[52335]296
[60482]297 pResult->s.Hi += (uint32_t)uHiValue1 * uHiValue2;
[52335]298 return pResult;
299}
300
301
[60482]302DECLINLINE(PRTUINT64U) RTUInt64DivRem(PRTUINT64U pQuotient, PRTUINT64U pRemainder, PCRTUINT64U pValue1, PCRTUINT64U pValue2);
[52335]303
304/**
[60482]305 * Divides a 64-bit unsigned integer value by another.
[52335]306 *
307 * @returns pResult
308 * @param pResult The result variable.
309 * @param pValue1 The dividend value.
310 * @param pValue2 The divisor value.
311 */
[60482]312DECLINLINE(PRTUINT64U) RTUInt64Div(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]313{
[60482]314 RTUINT64U Ignored;
315 return RTUInt64DivRem(pResult, &Ignored, pValue1, pValue2);
[52335]316}
317
318
319/**
[60482]320 * Divides a 64-bit unsigned integer value by another, returning the remainder.
[52335]321 *
322 * @returns pResult
323 * @param pResult The result variable (remainder).
324 * @param pValue1 The dividend value.
325 * @param pValue2 The divisor value.
326 */
[60482]327DECLINLINE(PRTUINT64U) RTUInt64Mod(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]328{
[60482]329 RTUINT64U Ignored;
330 RTUInt64DivRem(&Ignored, pResult, pValue1, pValue2);
[52335]331 return pResult;
332}
333
334
335/**
[60482]336 * Bitwise AND of two 64-bit unsigned integer values.
[52335]337 *
338 * @returns pResult
339 * @param pResult The result variable.
340 * @param pValue1 The first value.
341 * @param pValue2 The second value.
342 */
[60482]343DECLINLINE(PRTUINT64U) RTUInt64And(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]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/**
[60482]352 * Bitwise OR of two 64-bit unsigned integer values.
[52335]353 *
354 * @returns pResult
355 * @param pResult The result variable.
356 * @param pValue1 The first value.
357 * @param pValue2 The second value.
358 */
[60482]359DECLINLINE(PRTUINT64U) RTUInt64Or( PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]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/**
[60482]368 * Bitwise XOR of two 64-bit unsigned integer values.
[52335]369 *
370 * @returns pResult
371 * @param pResult The result variable.
372 * @param pValue1 The first value.
373 * @param pValue2 The second value.
374 */
[60482]375DECLINLINE(PRTUINT64U) RTUInt64Xor(PRTUINT64U pResult, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]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/**
[60482]384 * Shifts a 64-bit unsigned integer value @a cBits to the left.
[52335]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 */
[60482]391DECLINLINE(PRTUINT64U) RTUInt64ShiftLeft(PRTUINT64U pResult, PCRTUINT64U pValue, int cBits)
[52335]392{
[60482]393 cBits &= 63;
394 if (cBits < 32)
[52335]395 {
396 pResult->s.Lo = pValue->s.Lo << cBits;
[60482]397 pResult->s.Hi = (pValue->s.Hi << cBits) | (pValue->s.Lo >> (32 - cBits));
[52335]398 }
399 else
400 {
401 pResult->s.Lo = 0;
[60482]402 pResult->s.Hi = pValue->s.Lo << (cBits - 32);
[52335]403 }
404 return pResult;
405}
406
407
408/**
[60482]409 * Shifts a 64-bit unsigned integer value @a cBits to the right.
[52335]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 */
[60482]416DECLINLINE(PRTUINT64U) RTUInt64ShiftRight(PRTUINT64U pResult, PCRTUINT64U pValue, int cBits)
[52335]417{
[60482]418 cBits &= 63;
419 if (cBits < 32)
[52335]420 {
421 pResult->s.Hi = pValue->s.Hi >> cBits;
[60482]422 pResult->s.Lo = (pValue->s.Lo >> cBits) | (pValue->s.Hi << (32 - cBits));
[52335]423 }
424 else
425 {
426 pResult->s.Hi = 0;
[60482]427 pResult->s.Lo = pValue->s.Hi >> (cBits - 32);
[52335]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 */
[60482]440DECLINLINE(PRTUINT64U) RTUInt64BooleanNot(PRTUINT64U pResult, PCRTUINT64U pValue)
[52335]441{
[60482]442 pResult->s.Lo = pValue->s.Lo || pValue->s.Hi ? 0 : 1;
[52335]443 pResult->s.Hi = 0;
444 return pResult;
445}
446
447
448/**
[60482]449 * Bitwise not (flips each bit of the 64 bits).
[52335]450 *
451 * @returns pResult.
452 * @param pResult The result variable.
453 * @param pValue The value.
454 */
[60482]455DECLINLINE(PRTUINT64U) RTUInt64BitwiseNot(PRTUINT64U pResult, PCRTUINT64U pValue)
[52335]456{
457 pResult->s.Hi = ~pValue->s.Hi;
458 pResult->s.Lo = ~pValue->s.Lo;
459 return pResult;
460}
461
462
463/**
[60482]464 * Assigns one 64-bit unsigned integer value to another.
[35488]465 *
466 * @returns pResult
467 * @param pResult The result variable.
468 * @param pValue The value to assign.
469 */
[60482]470DECLINLINE(PRTUINT64U) RTUInt64Assign(PRTUINT64U pResult, PCRTUINT64U pValue)
[35488]471{
[60482]472#if ARCH_BITS >= 32
[35488]473 pResult->s.Hi = pValue->s.Hi;
474 pResult->s.Lo = pValue->s.Lo;
475#else
[60482]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;
[35488]480#endif
481 return pResult;
482}
483
484
485/**
[60482]486 * Assigns a boolean value to 64-bit unsigned integer.
[35488]487 *
[57944]488 * @returns pValueResult
489 * @param pValueResult The result variable.
[35488]490 * @param fValue The boolean value.
491 */
[60482]492DECLINLINE(PRTUINT64U) RTUInt64AssignBoolean(PRTUINT64U pValueResult, bool fValue)
[35488]493{
[60482]494#if ARCH_BITS >= 32
[35488]495 pValueResult->s.Lo = fValue;
496 pValueResult->s.Hi = 0;
497#else
[60482]498 pValueResult->Words.w0 = fValue;
499 pValueResult->Words.w1 = 0;
500 pValueResult->Words.w2 = 0;
501 pValueResult->Words.w3 = 0;
[35488]502#endif
503 return pValueResult;
504}
505
506
507/**
[60482]508 * Assigns a 8-bit unsigned integer value to 64-bit unsigned integer.
[35488]509 *
[57944]510 * @returns pValueResult
511 * @param pValueResult The result variable.
[35488]512 * @param u8Value The 8-bit unsigned integer value.
513 */
[60482]514DECLINLINE(PRTUINT64U) RTUInt64AssignU8(PRTUINT64U pValueResult, uint8_t u8Value)
[35488]515{
[60482]516#if ARCH_BITS >= 32
[35488]517 pValueResult->s.Lo = u8Value;
518 pValueResult->s.Hi = 0;
519#else
[60482]520 pValueResult->Words.w0 = u8Value;
521 pValueResult->Words.w1 = 0;
522 pValueResult->Words.w2 = 0;
523 pValueResult->Words.w3 = 0;
[35488]524#endif
525 return pValueResult;
526}
527
528
529/**
[60482]530 * Assigns a 16-bit unsigned integer value to 64-bit unsigned integer.
[35488]531 *
[57944]532 * @returns pValueResult
533 * @param pValueResult The result variable.
[35488]534 * @param u16Value The 16-bit unsigned integer value.
535 */
[60482]536DECLINLINE(PRTUINT64U) RTUInt64AssignU16(PRTUINT64U pValueResult, uint16_t u16Value)
[35488]537{
[60482]538#if ARCH_BITS >= 32
[35488]539 pValueResult->s.Lo = u16Value;
540 pValueResult->s.Hi = 0;
541#else
[60482]542 pValueResult->Words.w0 = u16Value;
543 pValueResult->Words.w1 = 0;
544 pValueResult->Words.w2 = 0;
545 pValueResult->Words.w3 = 0;
[35488]546#endif
547 return pValueResult;
548}
549
550
551/**
[60482]552 * Assigns a 32-bit unsigned integer value to 64-bit unsigned integer.
[35488]553 *
[57944]554 * @returns pValueResult
555 * @param pValueResult The result variable.
[35488]556 * @param u32Value The 32-bit unsigned integer value.
557 */
[60482]558DECLINLINE(PRTUINT64U) RTUInt64AssignU32(PRTUINT64U pValueResult, uint32_t u32Value)
[35488]559{
[60482]560#if ARCH_BITS >= 32
[35488]561 pValueResult->s.Lo = u32Value;
562 pValueResult->s.Hi = 0;
563#else
[60482]564 pValueResult->Words.w0 = (uint16_t)u32Value;
565 pValueResult->Words.w1 = u32Value >> 16;
566 pValueResult->Words.w2 = 0;
567 pValueResult->Words.w3 = 0;
[35488]568#endif
569 return pValueResult;
570}
571
572
573/**
[60482]574 * Adds two 64-bit unsigned integer values, storing the result in the first.
[35488]575 *
[52335]576 * @returns pValue1Result.
577 * @param pValue1Result The first value and result.
578 * @param pValue2 The second value.
579 */
[60482]580DECLINLINE(PRTUINT64U) RTUInt64AssignAdd(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
[52335]581{
[60482]582 uint32_t const uTmp = pValue1Result->s.Lo;
[52335]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}
[35488]589
590
591/**
[60482]592 * Subtracts two 64-bit unsigned integer values, storing the result in the
[52335]593 * first.
594 *
595 * @returns pValue1Result.
596 * @param pValue1Result The minuend value and result.
597 * @param pValue2 The subtrahend value.
598 */
[60482]599DECLINLINE(PRTUINT64U) RTUInt64AssignSub(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
[52335]600{
[60482]601 uint32_t const uTmp = pValue1Result->s.Lo;
[52335]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/**
[60482]611 * Multiplies two 64-bit unsigned integer values, storing the result in the
[52335]612 * first.
613 *
614 * @returns pValue1Result.
615 * @param pValue1Result The first value and result.
616 * @param pValue2 The second value.
617 */
[60482]618DECLINLINE(PRTUINT64U) RTUInt64AssignMul(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
[52335]619{
[60482]620 RTUINT64U Result;
621 RTUInt64Mul(&Result, pValue1Result, pValue2);
[52335]622 *pValue1Result = Result;
623 return pValue1Result;
624}
625
626
627/**
[60482]628 * Divides a 64-bit unsigned integer value by another, storing the result in
[52335]629 * the first.
630 *
631 * @returns pValue1Result.
632 * @param pValue1Result The dividend value and result.
633 * @param pValue2 The divisor value.
634 */
[60482]635DECLINLINE(PRTUINT64U) RTUInt64AssignDiv(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
[52335]636{
[60482]637 RTUINT64U Result;
638 RTUINT64U Ignored;
639 RTUInt64DivRem(&Result, &Ignored, pValue1Result, pValue2);
[52335]640 *pValue1Result = Result;
641 return pValue1Result;
642}
643
644
645/**
[60482]646 * Divides a 64-bit unsigned integer value by another, storing the remainder in
[52335]647 * the first.
648 *
649 * @returns pValue1Result.
650 * @param pValue1Result The dividend value and result (remainder).
651 * @param pValue2 The divisor value.
652 */
[60482]653DECLINLINE(PRTUINT64U) RTUInt64AssignMod(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
[52335]654{
[60482]655 RTUINT64U Ignored;
656 RTUINT64U Result;
657 RTUInt64DivRem(&Ignored, &Result, pValue1Result, pValue2);
[52335]658 *pValue1Result = Result;
659 return pValue1Result;
660}
661
662
663/**
[60482]664 * Performs a bitwise AND of two 64-bit unsigned integer values and assigned
[35488]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 */
[60482]671DECLINLINE(PRTUINT64U) RTUInt64AssignAnd(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
[35488]672{
[60482]673#if ARCH_BITS >= 32
[35488]674 pValue1Result->s.Hi &= pValue2->s.Hi;
675 pValue1Result->s.Lo &= pValue2->s.Lo;
676#else
[60482]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;
[35488]681#endif
682 return pValue1Result;
683}
684
685
686/**
[60482]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.
[35490]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 */
[60482]695DECLINLINE(PRTUINT64U) RTUInt64AssignAndNFirstBits(PRTUINT64U pValueResult, unsigned cBits)
[35490]696{
[60482]697 if (cBits <= 32)
[35490]698 {
[60482]699 if (cBits != 32)
700 pValueResult->s.Lo &= (RT_BIT_32(cBits) - 1);
[35490]701 pValueResult->s.Hi = 0;
702 }
[60482]703 else if (cBits < 64)
704 pValueResult->s.Hi &= (RT_BIT_32(cBits - 32) - 1);
[35490]705 return pValueResult;
706}
707
708
709/**
[60482]710 * Performs a bitwise OR of two 64-bit unsigned integer values and assigned
[35488]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 */
[60482]717DECLINLINE(PRTUINT64U) RTUInt64AssignOr(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
[35488]718{
[60482]719#if ARCH_BITS >= 32
[35488]720 pValue1Result->s.Hi |= pValue2->s.Hi;
721 pValue1Result->s.Lo |= pValue2->s.Lo;
722#else
[60482]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;
[35488]727#endif
728 return pValue1Result;
729}
730
731
732/**
[52335]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 */
[60482]739DECLINLINE(PRTUINT64U) RTUInt64AssignOrBit(PRTUINT64U pValue1Result, unsigned iBit)
[52335]740{
[60482]741#if ARCH_BITS >= 32
742 if (iBit >= 32)
743 pValue1Result->s.Hi |= RT_BIT_32(iBit - 32);
[52335]744 else
[60482]745 pValue1Result->s.Lo |= RT_BIT_32(iBit);
[52335]746#else
[60482]747 if (iBit >= 32)
[52335]748 {
[60482]749 if (iBit >= 48)
750 pValue1Result->Words.w3 |= UINT16_C(1) << (iBit - 48);
[52335]751 else
[60482]752 pValue1Result->Words.w2 |= UINT16_C(1) << (iBit - 32);
[52335]753 }
754 else
755 {
[60482]756 if (iBit >= 16)
757 pValue1Result->Words.w1 |= UINT16_C(1) << (iBit - 16);
[52335]758 else
[60482]759 pValue1Result->Words.w0 |= UINT16_C(1) << (iBit);
[52335]760 }
761#endif
762 return pValue1Result;
763}
764
765
766
767/**
[60482]768 * Performs a bitwise XOR of two 64-bit unsigned integer values and assigned
[35488]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 */
[60482]775DECLINLINE(PRTUINT64U) RTUInt64AssignXor(PRTUINT64U pValue1Result, PCRTUINT64U pValue2)
[35488]776{
[60482]777#if ARCH_BITS >= 32
[35488]778 pValue1Result->s.Hi ^= pValue2->s.Hi;
779 pValue1Result->s.Lo ^= pValue2->s.Lo;
780#else
[60482]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;
[35488]785#endif
786 return pValue1Result;
787}
788
789
790/**
[60482]791 * Performs a bitwise left shift on a 64-bit unsigned integer value, assigning
[35488]792 * the result to it.
793 *
[57944]794 * @returns pValueResult.
795 * @param pValueResult The first value and result.
[35488]796 * @param cBits The number of bits to shift.
797 */
[60482]798DECLINLINE(PRTUINT64U) RTUInt64AssignShiftLeft(PRTUINT64U pValueResult, int cBits)
[35488]799{
[60482]800 RTUINT64U const InVal = *pValueResult;
[35488]801 if (cBits > 0)
802 {
803 /* (left shift) */
[60485]804 cBits &= 31;
[60484]805 if (cBits >= 32)
[35488]806 {
807 pValueResult->s.Lo = 0;
[60482]808 pValueResult->s.Hi = InVal.s.Lo << (cBits - 32);
[35488]809 }
810 else
811 {
812 pValueResult->s.Hi = InVal.s.Hi << cBits;
[60482]813 pValueResult->s.Hi |= InVal.s.Lo >> (32 - cBits);
[35488]814 pValueResult->s.Lo = InVal.s.Lo << cBits;
815 }
816 }
817 else if (cBits < 0)
818 {
819 /* (right shift) */
820 cBits = -cBits;
[60485]821 cBits &= 31;
[60484]822 if (cBits >= 32)
[35488]823 {
824 pValueResult->s.Hi = 0;
[60482]825 pValueResult->s.Lo = InVal.s.Hi >> (cBits - 32);
[35488]826 }
827 else
828 {
829 pValueResult->s.Lo = InVal.s.Lo >> cBits;
[60482]830 pValueResult->s.Lo |= InVal.s.Hi << (32 - cBits);
[35488]831 pValueResult->s.Hi = InVal.s.Hi >> cBits;
832 }
833 }
834 return pValueResult;
835}
836
837
838/**
[60482]839 * Performs a bitwise left shift on a 64-bit unsigned integer value, assigning
[35488]840 * the result to it.
841 *
[57944]842 * @returns pValueResult.
843 * @param pValueResult The first value and result.
[35488]844 * @param cBits The number of bits to shift.
845 */
[60482]846DECLINLINE(PRTUINT64U) RTUInt64AssignShiftRight(PRTUINT64U pValueResult, int cBits)
[35488]847{
[60482]848 return RTUInt64AssignShiftLeft(pValueResult, -cBits);
[35488]849}
850
851
852/**
[60482]853 * Performs a bitwise NOT on a 64-bit unsigned integer value, assigning the
[35488]854 * result to it.
855 *
856 * @returns pValueResult
857 * @param pValueResult The value and result.
858 */
[60482]859DECLINLINE(PRTUINT64U) RTUInt64AssignBitwiseNot(PRTUINT64U pValueResult)
[35488]860{
[60482]861#if ARCH_BITS >= 32
[35488]862 pValueResult->s.Hi = ~pValueResult->s.Hi;
863 pValueResult->s.Lo = ~pValueResult->s.Lo;
864#else
[60482]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;
[35488]869#endif
870 return pValueResult;
871}
872
873
874/**
[60482]875 * Performs a boolean NOT on a 64-bit unsigned integer value, assigning the
[35488]876 * result to it.
877 *
878 * @returns pValueResult
879 * @param pValueResult The value and result.
880 */
[60482]881DECLINLINE(PRTUINT64U) RTUInt64AssignBooleanNot(PRTUINT64U pValueResult)
[35488]882{
[60482]883 return RTUInt64AssignBoolean(pValueResult, RTUInt64IsZero(pValueResult));
[35488]884}
885
886
887/**
[60482]888 * Compares two 64-bit unsigned integer values.
[35488]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 */
[60482]897DECLINLINE(int) RTUInt64Compare(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[35488]898{
[60482]899#if ARCH_BITS >= 32
[35488]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
[60482]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;
[35488]914 return 0;
915#endif
916}
917
918
919/**
[60482]920 * Tests if a 64-bit unsigned integer value is smaller than another.
[52335]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 */
[60482]926DECLINLINE(bool) RTUInt64IsSmaller(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]927{
[60482]928#if ARCH_BITS >= 32
[52335]929 return pValue1->s.Hi < pValue2->s.Hi
930 || ( pValue1->s.Hi == pValue2->s.Hi
931 && pValue1->s.Lo < pValue2->s.Lo);
932#else
[60482]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)))));
[52335]940#endif
941}
942
943
944/**
[60482]945 * Tests if a 32-bit unsigned integer value is larger than another.
[52335]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 */
[60482]951DECLINLINE(bool) RTUInt64IsLarger(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]952{
[60482]953#if ARCH_BITS >= 32
[52335]954 return pValue1->s.Hi > pValue2->s.Hi
955 || ( pValue1->s.Hi == pValue2->s.Hi
956 && pValue1->s.Lo > pValue2->s.Lo);
957#else
[60482]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)))));
[52335]965#endif
966}
967
968
969/**
[60482]970 * Tests if a 64-bit unsigned integer value is larger or equal than another.
[52335]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 */
[60482]976DECLINLINE(bool) RTUInt64IsLargerOrEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]977{
[60482]978#if ARCH_BITS >= 32
[52335]979 return pValue1->s.Hi > pValue2->s.Hi
980 || ( pValue1->s.Hi == pValue2->s.Hi
981 && pValue1->s.Lo >= pValue2->s.Lo);
982#else
[60482]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)))));
[52335]990#endif
991}
992
993
994/**
[60482]995 * Tests if two 64-bit unsigned integer values not equal.
[35488]996 *
997 * @returns true if equal, false if not equal.
998 * @param pValue1 The first value.
999 * @param pValue2 The second value.
1000 */
[60482]1001DECLINLINE(bool) RTUInt64IsEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[35488]1002{
[60482]1003#if ARCH_BITS >= 32
[35488]1004 return pValue1->s.Hi == pValue2->s.Hi
1005 && pValue1->s.Lo == pValue2->s.Lo;
1006#else
[60482]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;
[35488]1011#endif
1012}
1013
1014
1015/**
[60482]1016 * Tests if two 64-bit unsigned integer values are not equal.
[35488]1017 *
1018 * @returns true if not equal, false if equal.
1019 * @param pValue1 The first value.
1020 * @param pValue2 The second value.
1021 */
[60482]1022DECLINLINE(bool) RTUInt64IsNotEqual(PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[35488]1023{
[60482]1024 return !RTUInt64IsEqual(pValue1, pValue2);
[35488]1025}
1026
1027
1028/**
[60482]1029 * Sets a bit in a 64-bit unsigned integer type.
[35488]1030 *
1031 * @returns pValueResult.
1032 * @param pValueResult The input and output value.
1033 * @param iBit The bit to set.
1034 */
[60482]1035DECLINLINE(PRTUINT64U) RTUInt64BitSet(PRTUINT64U pValueResult, unsigned iBit)
[35488]1036{
[60482]1037 if (iBit < 32)
[35488]1038 {
[60482]1039#if ARCH_BITS >= 32
1040 pValueResult->s.Lo |= RT_BIT_32(iBit);
[35488]1041#else
[60482]1042 if (iBit < 16)
1043 pValueResult->Words.w0 |= UINT16_C(1) << iBit;
[35488]1044 else
[60482]1045 pValueResult->Words.w1 |= UINT16_C(1) << (iBit - 32);
[35488]1046#endif
1047 }
[60482]1048 else if (iBit < 64)
[35488]1049 {
[60482]1050#if ARCH_BITS >= 32
[60484]1051 pValueResult->s.Hi |= RT_BIT_32(iBit - 32);
[35488]1052#else
[60482]1053 if (iBit < 48)
1054 pValueResult->Words.w2 |= UINT16_C(1) << (iBit - 64);
[35488]1055 else
[60482]1056 pValueResult->Words.w3 |= UINT16_C(1) << (iBit - 96);
[35488]1057#endif
1058 }
1059 return pValueResult;
1060}
1061
1062
1063/**
[60482]1064 * Sets a bit in a 64-bit unsigned integer type.
[35488]1065 *
1066 * @returns pValueResult.
1067 * @param pValueResult The input and output value.
1068 * @param iBit The bit to set.
1069 */
[60482]1070DECLINLINE(PRTUINT64U) RTUInt64BitClear(PRTUINT64U pValueResult, unsigned iBit)
[35488]1071{
[60482]1072 if (iBit < 32)
[35488]1073 {
[60482]1074#if ARCH_BITS >= 32
1075 pValueResult->s.Lo &= ~RT_BIT_32(iBit);
[35488]1076#else
[60482]1077 if (iBit < 48)
1078 pValueResult->Words.w0 &= ~(UINT16_C(1) << (iBit));
[35488]1079 else
[60482]1080 pValueResult->Words.w1 &= ~(UINT16_C(1) << (iBit - 32));
[35488]1081#endif
1082 }
[60482]1083 else if (iBit < 64)
[35488]1084 {
[60482]1085#if ARCH_BITS >= 32
1086 pValueResult->s.Hi &= ~RT_BIT_32(iBit - 32);
[35488]1087#else
[60482]1088 if (iBit < 48)
1089 pValueResult->Words.w2 &= ~(UINT16_C(1) << (iBit - 64));
[35488]1090 else
[60482]1091 pValueResult->Words.w3 &= ~(UINT16_C(1) << (iBit - 96));
[35488]1092#endif
1093 }
1094 return pValueResult;
1095}
1096
1097
1098/**
[60482]1099 * Tests if a bit in a 64-bit unsigned integer value is set.
[35488]1100 *
1101 * @returns pValueResult.
1102 * @param pValueResult The input and output value.
1103 * @param iBit The bit to test.
1104 */
[60482]1105DECLINLINE(bool) RTUInt64BitTest(PRTUINT64U pValueResult, unsigned iBit)
[35488]1106{
1107 bool fRc;
[60482]1108 if (iBit < 32)
[35488]1109 {
[60482]1110#if ARCH_BITS >= 32
1111 fRc = RT_BOOL(pValueResult->s.Lo & RT_BIT_32(iBit));
[35488]1112#else
[60482]1113 if (iBit < 16)
1114 fRc = RT_BOOL(pValueResult->Words.w0 & (UINT16_C(1) << (iBit)));
[35488]1115 else
[60482]1116 fRc = RT_BOOL(pValueResult->Words.w1 & (UINT16_C(1) << (iBit - 16)));
[35488]1117#endif
1118 }
[60482]1119 else if (iBit < 64)
[35488]1120 {
[60482]1121#if ARCH_BITS >= 32
[60484]1122 fRc = RT_BOOL(pValueResult->s.Hi & RT_BIT_32(iBit - 32));
[35488]1123#else
[60482]1124 if (iBit < 48)
1125 fRc = RT_BOOL(pValueResult->Words.w2 & (UINT16_C(1) << (iBit - 32)));
[35488]1126 else
[60482]1127 fRc = RT_BOOL(pValueResult->Words.w3 & (UINT16_C(1) << (iBit - 48)));
[35488]1128#endif
1129 }
1130 else
1131 fRc = false;
1132 return fRc;
1133}
1134
1135
1136/**
[60482]1137 * Set a range of bits a 64-bit unsigned integer value.
[35488]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 */
[60482]1144DECLINLINE(PRTUINT64U) RTUInt64BitSetRange(PRTUINT64U pValueResult, unsigned iFirstBit, unsigned cBits)
[35488]1145{
1146 /* bounds check & fix. */
[60482]1147 if (iFirstBit < 64)
[35488]1148 {
[60482]1149 if (iFirstBit + cBits > 64)
1150 cBits = 64 - iFirstBit;
[35488]1151
[60482]1152#if ARCH_BITS >= 32
[35488]1153 if (iFirstBit + cBits < 32)
[60482]1154 pValueResult->s.Lo |= (RT_BIT_32(cBits) - 1) << iFirstBit;
[35488]1155 else if (iFirstBit + cBits < 64 && iFirstBit >= 32)
[60482]1156 pValueResult->s.Hi |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 32);
[35488]1157 else
[60482]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
[35488]1168#endif
1169 while (cBits-- > 0)
[60482]1170 RTUInt64BitSet(pValueResult, iFirstBit++);
[35488]1171 }
1172 return pValueResult;
1173}
1174
1175
1176/**
[60482]1177 * Test if all the bits of a 64-bit unsigned integer value are set.
[35488]1178 *
1179 * @returns true if they are, false if they aren't.
1180 * @param pValue The input and output value.
1181 */
[60482]1182DECLINLINE(bool) RTUInt64BitAreAllSet(PRTUINT64U pValue)
[35488]1183{
[60482]1184#if ARCH_BITS >= 32
1185 return pValue->s.Hi == UINT32_MAX
1186 && pValue->s.Lo == UINT32_MAX;
[35488]1187#else
[60482]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;
[35488]1192#endif
1193}
1194
1195
1196/**
[60482]1197 * Test if all the bits of a 64-bit unsigned integer value are clear.
[35488]1198 *
1199 * @returns true if they are, false if they aren't.
1200 * @param pValue The input and output value.
1201 */
[60482]1202DECLINLINE(bool) RTUInt64BitAreAllClear(PRTUINT64U pValue)
[35488]1203{
[60482]1204 return RTUInt64IsZero(pValue);
[35488]1205}
1206
[52335]1207
[60482]1208DECLINLINE(unsigned) RTUInt64BitCount(PCRTUINT64U pValue)
[52335]1209{
[60482]1210 unsigned cBits;
[52335]1211 if (pValue->s.Hi != 0)
1212 {
[60482]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);
[52335]1218 else
[60482]1219 cBits = 32 + ASMBitLastSetU16(pValue->Words.w2);
1220#endif
[52335]1221 }
1222 else
1223 {
[60482]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);
[52335]1229 else
[60482]1230 cBits = 0 + ASMBitLastSetU16(pValue->Words.w0);
1231#endif
[52335]1232 }
1233 return cBits;
1234}
1235
1236
1237/**
[60482]1238 * Divides a 64-bit unsigned integer value by another, returning both quotient
[52335]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 */
[60482]1247DECLINLINE(PRTUINT64U) RTUInt64DivRem(PRTUINT64U pQuotient, PRTUINT64U pRemainder, PCRTUINT64U pValue1, PCRTUINT64U pValue2)
[52335]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 {
[60482]1262 RTUInt64SetZero(pRemainder);
[52335]1263 *pQuotient = *pValue1;
1264 return pQuotient;
1265 }
[60482]1266 /** @todo RTUInt64DivModByU32 */
[52335]1267 }
1268
1269 /* Dividend is smaller? */
[60482]1270 iDiff = RTUInt64Compare(pValue1, pValue2);
[52335]1271 if (iDiff < 0)
1272 {
1273 *pRemainder = *pValue1;
[60482]1274 RTUInt64SetZero(pQuotient);
[52335]1275 }
1276
1277 /* The values are equal? */
1278 else if (iDiff == 0)
1279 {
[60482]1280 RTUInt64SetZero(pRemainder);
1281 RTUInt64AssignU8(pQuotient, 1);
[52335]1282 }
1283 else
1284 {
1285 /*
1286 * Prepare.
1287 */
[60482]1288 unsigned iBitAdder = RTUInt64BitCount(pValue1) - RTUInt64BitCount(pValue2);
1289 RTUINT64U NormDivisor = *pValue2;
[52335]1290 if (iBitAdder)
1291 {
[60482]1292 RTUInt64ShiftLeft(&NormDivisor, pValue2, iBitAdder);
1293 if (RTUInt64IsLarger(&NormDivisor, pValue1))
[52335]1294 {
[60482]1295 RTUInt64AssignShiftRight(&NormDivisor, 1);
[52335]1296 iBitAdder--;
1297 }
1298 }
1299 else
1300 NormDivisor = *pValue2;
1301
[60482]1302 RTUInt64SetZero(pQuotient);
[52335]1303 *pRemainder = *pValue1;
1304
1305 /*
1306 * Do the division.
1307 */
[60482]1308 if (RTUInt64IsLargerOrEqual(pRemainder, pValue2))
[52335]1309 {
1310 for (;;)
1311 {
[60482]1312 if (RTUInt64IsLargerOrEqual(pRemainder, &NormDivisor))
[52335]1313 {
[60482]1314 RTUInt64AssignSub(pRemainder, &NormDivisor);
1315 RTUInt64AssignOrBit(pQuotient, iBitAdder);
[52335]1316 }
[60482]1317 if (RTUInt64IsSmaller(pRemainder, pValue2))
[52335]1318 break;
[60482]1319 RTUInt64AssignShiftRight(&NormDivisor, 1);
[52335]1320 iBitAdder--;
1321 }
1322 }
1323 }
1324 return pQuotient;
1325}
1326
1327
[35488]1328/** @} */
1329
1330RT_C_DECLS_END
1331
[76585]1332#endif /* !IPRT_INCLUDED_uint64_h */
[35488]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