VirtualBox

source: vbox/trunk/include/iprt/uint256.h

Last change on this file 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.7 KB
RevLine 
[35488]1/** @file
[94511]2 * IPRT - RTUINT256U methods.
[35488]3 */
4
5/*
[98103]6 * Copyright (C) 2011-2023 Oracle and/or its affiliates.
[35488]7 *
[96407]8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
[35488]10 *
[96407]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 *
[35488]24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
[96407]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
[35488]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.
[96407]32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
[35488]34 */
35
[94511]36#ifndef IPRT_INCLUDED_uint256_h
37#define IPRT_INCLUDED_uint256_h
[76507]38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
[35488]41
42#include <iprt/cdefs.h>
43#include <iprt/types.h>
[52335]44#include <iprt/asm.h>
[94513]45#include <iprt/asm-math.h>
[35488]46
47RT_C_DECLS_BEGIN
48
[94511]49/** @defgroup grp_rt_uint256 RTUInt256 - 256-bit Unsigned Integer Methods
[35488]50 * @ingroup grp_rt
51 * @{
52 */
53
54
55/**
[94511]56 * Test if a 256-bit unsigned integer value is zero.
[35488]57 *
58 * @returns true if they are, false if they aren't.
59 * @param pValue The input and output value.
60 */
[94511]61DECLINLINE(bool) RTUInt256IsZero(PCRTUINT256U pValue)
[35488]62{
63#if ARCH_BITS >= 64
[94511]64 return pValue->QWords.qw0 == 0
65 && pValue->QWords.qw1 == 0
66 && pValue->QWords.qw2 == 0
67 && pValue->QWords.qw3 == 0;
[35488]68#else
69 return pValue->DWords.dw0 == 0
70 && pValue->DWords.dw1 == 0
71 && pValue->DWords.dw2 == 0
[94511]72 && pValue->DWords.dw3 == 0
73 && pValue->DWords.dw4 == 0
74 && pValue->DWords.dw5 == 0
75 && pValue->DWords.dw6 == 0
76 && pValue->DWords.dw7 == 0;
[35488]77#endif
78}
79
80
81/**
[94511]82 * Set a 256-bit unsigned integer value to zero.
[35488]83 *
84 * @returns pResult
85 * @param pResult The result variable.
86 */
[94511]87DECLINLINE(PRTUINT256U) RTUInt256SetZero(PRTUINT256U pResult)
[35488]88{
89#if ARCH_BITS >= 64
[94511]90 pResult->QWords.qw0 = 0;
91 pResult->QWords.qw1 = 0;
92 pResult->QWords.qw2 = 0;
93 pResult->QWords.qw3 = 0;
[35488]94#else
95 pResult->DWords.dw0 = 0;
96 pResult->DWords.dw1 = 0;
97 pResult->DWords.dw2 = 0;
98 pResult->DWords.dw3 = 0;
[94511]99 pResult->DWords.dw4 = 0;
100 pResult->DWords.dw5 = 0;
101 pResult->DWords.dw6 = 0;
102 pResult->DWords.dw7 = 0;
[35488]103#endif
104 return pResult;
105}
106
107
108/**
[94511]109 * Set a 256-bit unsigned integer value to the maximum value.
[35488]110 *
111 * @returns pResult
112 * @param pResult The result variable.
113 */
[94511]114DECLINLINE(PRTUINT256U) RTUInt256SetMax(PRTUINT256U pResult)
[35488]115{
116#if ARCH_BITS >= 64
[94511]117 pResult->QWords.qw0 = UINT64_MAX;
118 pResult->QWords.qw1 = UINT64_MAX;
119 pResult->QWords.qw2 = UINT64_MAX;
120 pResult->QWords.qw3 = UINT64_MAX;
[35488]121#else
122 pResult->DWords.dw0 = UINT32_MAX;
123 pResult->DWords.dw1 = UINT32_MAX;
124 pResult->DWords.dw2 = UINT32_MAX;
125 pResult->DWords.dw3 = UINT32_MAX;
[94511]126 pResult->DWords.dw4 = UINT32_MAX;
127 pResult->DWords.dw5 = UINT32_MAX;
128 pResult->DWords.dw6 = UINT32_MAX;
129 pResult->DWords.dw7 = UINT32_MAX;
[35488]130#endif
131 return pResult;
132}
133
134
135
136
137/**
[94511]138 * Adds two 256-bit unsigned integer values.
[52335]139 *
140 * @returns pResult
141 * @param pResult The result variable.
142 * @param pValue1 The first value.
143 * @param pValue2 The second value.
144 */
[94511]145DECLINLINE(PRTUINT256U) RTUInt256Add(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]146{
[94511]147 unsigned uCarry;
148 pResult->QWords.qw0 = pValue1->QWords.qw0 + pValue2->QWords.qw0;
149 uCarry = pResult->QWords.qw0 < pValue1->QWords.qw0;
150
151 pResult->QWords.qw1 = pValue1->QWords.qw1 + pValue2->QWords.qw1 + uCarry;
152 uCarry = uCarry ? pResult->QWords.qw1 <= pValue1->QWords.qw1 : pResult->QWords.qw1 < pValue1->QWords.qw1;
153
154 pResult->QWords.qw2 = pValue1->QWords.qw2 + pValue2->QWords.qw2 + uCarry;
155 uCarry = uCarry ? pResult->QWords.qw2 <= pValue1->QWords.qw2 : pResult->QWords.qw2 < pValue1->QWords.qw2;
156
157 pResult->QWords.qw3 = pValue1->QWords.qw3 + pValue2->QWords.qw3 + uCarry;
[52335]158 return pResult;
159}
160
161
162/**
[94511]163 * Adds a 256-bit and a 64-bit unsigned integer values.
[52335]164 *
165 * @returns pResult
166 * @param pResult The result variable.
167 * @param pValue1 The first value.
168 * @param uValue2 The second value, 64-bit.
169 */
[94511]170DECLINLINE(PRTUINT256U) RTUInt256AddU64(PRTUINT256U pResult, PCRTUINT256U pValue1, uint64_t uValue2)
[52335]171{
[94511]172 pResult->QWords.qw3 = pValue1->QWords.qw3;
173 pResult->QWords.qw2 = pValue1->QWords.qw2;
174 pResult->QWords.qw1 = pValue1->QWords.qw1;
175 pResult->QWords.qw0 = pValue1->QWords.qw0 + uValue2;
176 if (pResult->QWords.qw0 < uValue2)
177 if (pResult->QWords.qw1++ == UINT64_MAX)
178 if (pResult->QWords.qw2++ == UINT64_MAX)
179 pResult->QWords.qw3++;
[52335]180 return pResult;
181}
182
183
184/**
[94511]185 * Subtracts a 256-bit unsigned integer value from another.
[52335]186 *
187 * @returns pResult
188 * @param pResult The result variable.
189 * @param pValue1 The minuend value.
190 * @param pValue2 The subtrahend value.
191 */
[94511]192DECLINLINE(PRTUINT256U) RTUInt256Sub(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]193{
[94511]194 unsigned uBorrow;
195 pResult->QWords.qw0 = pValue1->QWords.qw0 - pValue2->QWords.qw0;
196 uBorrow = pResult->QWords.qw0 > pValue1->QWords.qw0;
197
198 pResult->QWords.qw1 = pValue1->QWords.qw1 - pValue2->QWords.qw1 - uBorrow;
199 uBorrow = uBorrow ? pResult->QWords.qw1 >= pValue1->QWords.qw1 : pResult->QWords.qw1 > pValue1->QWords.qw1;
200
201 pResult->QWords.qw2 = pValue1->QWords.qw2 - pValue2->QWords.qw2 - uBorrow;
202 uBorrow = uBorrow ? pResult->QWords.qw2 >= pValue1->QWords.qw2 : pResult->QWords.qw2 > pValue1->QWords.qw2;
203
204 pResult->QWords.qw3 = pValue1->QWords.qw3 - pValue2->QWords.qw3 - uBorrow;
[52335]205 return pResult;
206}
207
208
209/**
[94511]210 * Multiplies two 256-bit unsigned integer values.
[52335]211 *
212 * @returns pResult
213 * @param pResult The result variable.
214 * @param pValue1 The first value.
215 * @param pValue2 The second value.
216 */
[94511]217RTDECL(PRTUINT256U) RTUInt256Mul(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2);
[52335]218
219/**
[94511]220 * Multiplies an 256-bit unsigned integer by a 64-bit unsigned integer value.
[52335]221 *
222 * @returns pResult
223 * @param pResult The result variable.
224 * @param pValue1 The first value.
225 * @param uValue2 The second value, 64-bit.
226 */
[94511]227RTDECL(PRTUINT256U) RTUInt256MulByU64(PRTUINT256U pResult, PCRTUINT256U pValue1, uint64_t uValue2);
[52335]228
229/**
[94511]230 * Divides a 256-bit unsigned integer value by another, returning both quotient
231 * and remainder.
[52335]232 *
[94511]233 * @returns pQuotient, NULL if pValue2 is 0.
234 * @param pQuotient Where to return the quotient.
235 * @param pRemainder Where to return the remainder.
236 * @param pValue1 The dividend value.
237 * @param pValue2 The divisor value.
[52335]238 */
[94511]239RTDECL(PRTUINT256U) RTUInt256DivRem(PRTUINT256U pQuotient, PRTUINT256U pRemainder, PCRTUINT256U pValue1, PCRTUINT256U pValue2);
[52335]240
241/**
[94511]242 * Divides a 256-bit unsigned integer value by another.
[52335]243 *
244 * @returns pResult
245 * @param pResult The result variable.
246 * @param pValue1 The dividend value.
247 * @param pValue2 The divisor value.
248 */
[94511]249DECLINLINE(PRTUINT256U) RTUInt256Div(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]250{
[94511]251 RTUINT256U Ignored;
252 return RTUInt256DivRem(pResult, &Ignored, pValue1, pValue2);
[52335]253}
254
255
256/**
[94511]257 * Divides a 256-bit unsigned integer value by another, returning the remainder.
[52335]258 *
259 * @returns pResult
260 * @param pResult The result variable (remainder).
261 * @param pValue1 The dividend value.
262 * @param pValue2 The divisor value.
263 */
[94511]264DECLINLINE(PRTUINT256U) RTUInt256Mod(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]265{
[94511]266 RTUINT256U Ignored;
267 RTUInt256DivRem(&Ignored, pResult, pValue1, pValue2);
[52335]268 return pResult;
269}
270
271
272/**
[94511]273 * Bitwise AND of two 256-bit unsigned integer values.
[52335]274 *
275 * @returns pResult
276 * @param pResult The result variable.
277 * @param pValue1 The first value.
278 * @param pValue2 The second value.
279 */
[94511]280DECLINLINE(PRTUINT256U) RTUInt256And(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]281{
[94511]282 pResult->QWords.qw0 = pValue1->QWords.qw0 & pValue2->QWords.qw0;
283 pResult->QWords.qw1 = pValue1->QWords.qw1 & pValue2->QWords.qw1;
284 pResult->QWords.qw2 = pValue1->QWords.qw2 & pValue2->QWords.qw2;
285 pResult->QWords.qw3 = pValue1->QWords.qw3 & pValue2->QWords.qw3;
[52335]286 return pResult;
287}
288
289
290/**
[94511]291 * Bitwise OR of two 256-bit unsigned integer values.
[52335]292 *
293 * @returns pResult
294 * @param pResult The result variable.
295 * @param pValue1 The first value.
296 * @param pValue2 The second value.
297 */
[94511]298DECLINLINE(PRTUINT256U) RTUInt256Or( PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]299{
[94511]300 pResult->QWords.qw0 = pValue1->QWords.qw0 | pValue2->QWords.qw0;
301 pResult->QWords.qw1 = pValue1->QWords.qw1 | pValue2->QWords.qw1;
302 pResult->QWords.qw2 = pValue1->QWords.qw2 | pValue2->QWords.qw2;
303 pResult->QWords.qw3 = pValue1->QWords.qw3 | pValue2->QWords.qw3;
[52335]304 return pResult;
305}
306
307
308/**
[94511]309 * Bitwise XOR of two 256-bit unsigned integer values.
[52335]310 *
311 * @returns pResult
312 * @param pResult The result variable.
313 * @param pValue1 The first value.
314 * @param pValue2 The second value.
315 */
[94511]316DECLINLINE(PRTUINT256U) RTUInt256Xor(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]317{
[94511]318 pResult->QWords.qw0 = pValue1->QWords.qw0 ^ pValue2->QWords.qw0;
319 pResult->QWords.qw1 = pValue1->QWords.qw1 ^ pValue2->QWords.qw1;
320 pResult->QWords.qw2 = pValue1->QWords.qw2 ^ pValue2->QWords.qw2;
321 pResult->QWords.qw3 = pValue1->QWords.qw3 ^ pValue2->QWords.qw3;
[52335]322 return pResult;
323}
324
325
326/**
[94511]327 * Shifts a 256-bit unsigned integer value @a cBits to the left.
[52335]328 *
329 * @returns pResult
330 * @param pResult The result variable.
331 * @param pValue The value to shift.
[94511]332 * @param cBits The number of bits to shift it. This is masked
333 * by 255 before shifting.
[52335]334 */
[94511]335DECLINLINE(PRTUINT256U) RTUInt256ShiftLeft(PRTUINT256U pResult, PCRTUINT256U pValue, unsigned cBits)
[52335]336{
[94511]337 /* This is a bit bulky & impractical since we cannot access the data using
338 an array because it is organized according to host endianness. Sigh. */
339 cBits &= 255;
340 if (!(cBits & 0x3f))
[52335]341 {
[94511]342 if (cBits == 0)
343 *pResult = *pValue;
344 else
345 {
346 pResult->QWords.qw0 = 0;
347 if (cBits == 64)
348 {
349 pResult->QWords.qw1 = pValue->QWords.qw0;
350 pResult->QWords.qw2 = pValue->QWords.qw1;
351 pResult->QWords.qw3 = pValue->QWords.qw2;
352 }
353 else
354 {
355 pResult->QWords.qw1 = 0;
356 if (cBits == 128)
357 {
358 pResult->QWords.qw2 = pValue->QWords.qw0;
359 pResult->QWords.qw3 = pValue->QWords.qw1;
360 }
361 else
362 {
363 pResult->QWords.qw2 = 0;
364 pResult->QWords.qw3 = pValue->QWords.qw0;
365 }
366 }
367 }
[52335]368 }
[94511]369 else if (cBits < 128)
370 {
371 if (cBits < 64)
372 {
373 pResult->QWords.qw0 = pValue->QWords.qw0 << cBits;
374 pResult->QWords.qw1 = pValue->QWords.qw0 >> (64 - cBits);
375 pResult->QWords.qw1 |= pValue->QWords.qw1 << cBits;
376 pResult->QWords.qw2 = pValue->QWords.qw1 >> (64 - cBits);
377 pResult->QWords.qw2 |= pValue->QWords.qw2 << cBits;
378 pResult->QWords.qw3 = pValue->QWords.qw2 >> (64 - cBits);
379 pResult->QWords.qw3 |= pValue->QWords.qw3 << cBits;
380 }
381 else
382 {
383 cBits -= 64;
384 pResult->QWords.qw0 = 0;
385 pResult->QWords.qw1 = pValue->QWords.qw0 << cBits;
386 pResult->QWords.qw2 = pValue->QWords.qw0 >> (64 - cBits);
387 pResult->QWords.qw2 |= pValue->QWords.qw1 << cBits;
388 pResult->QWords.qw3 = pValue->QWords.qw1 >> (64 - cBits);
389 pResult->QWords.qw3 |= pValue->QWords.qw2 << cBits;
390 }
391 }
[52335]392 else
393 {
[94511]394 if (cBits < 192)
395 {
396 cBits -= 128;
397 pResult->QWords.qw0 = 0;
398 pResult->QWords.qw1 = 0;
399 pResult->QWords.qw2 = pValue->QWords.qw0 << cBits;
400 pResult->QWords.qw3 = pValue->QWords.qw0 >> (64 - cBits);
401 pResult->QWords.qw3 |= pValue->QWords.qw1 << cBits;
402 }
403 else
404 {
405 cBits -= 192;
406 pResult->QWords.qw0 = 0;
407 pResult->QWords.qw1 = 0;
408 pResult->QWords.qw2 = 0;
409 pResult->QWords.qw3 = pValue->QWords.qw0 << cBits;
410 }
[52335]411 }
412 return pResult;
413}
414
415
416/**
[94511]417 * Shifts a 256-bit unsigned integer value @a cBits to the right.
[52335]418 *
419 * @returns pResult
420 * @param pResult The result variable.
421 * @param pValue The value to shift.
[94511]422 * @param cBits The number of bits to shift it. This is masked
423 * by 255 before shifting.
[52335]424 */
[94511]425DECLINLINE(PRTUINT256U) RTUInt256ShiftRight(PRTUINT256U pResult, PCRTUINT256U pValue, unsigned cBits)
[52335]426{
[94511]427 /* This is a bit bulky & impractical since we cannot access the data using
428 an array because it is organized according to host endianness. Sigh. */
429 cBits &= 255;
430 if (!(cBits & 0x3f))
[52335]431 {
[94511]432 if (cBits == 0)
433 *pResult = *pValue;
434 else
435 {
436 if (cBits == 64)
437 {
438 pResult->QWords.qw0 = pValue->QWords.qw1;
439 pResult->QWords.qw1 = pValue->QWords.qw2;
440 pResult->QWords.qw2 = pValue->QWords.qw3;
441 }
442 else
443 {
444 if (cBits == 128)
445 {
446 pResult->QWords.qw0 = pValue->QWords.qw2;
447 pResult->QWords.qw1 = pValue->QWords.qw3;
448 }
449 else
450 {
451 pResult->QWords.qw0 = pValue->QWords.qw3;
452 pResult->QWords.qw1 = 0;
453 }
454 pResult->QWords.qw2 = 0;
455 }
456 pResult->QWords.qw3 = 0;
457 }
[52335]458 }
[94511]459 else if (cBits < 128)
460 {
461 if (cBits < 64)
462 {
463 pResult->QWords.qw0 = pValue->QWords.qw0 >> cBits;
464 pResult->QWords.qw0 |= pValue->QWords.qw1 << (64 - cBits);
465 pResult->QWords.qw1 = pValue->QWords.qw1 >> cBits;
466 pResult->QWords.qw1 |= pValue->QWords.qw2 << (64 - cBits);
467 pResult->QWords.qw2 = pValue->QWords.qw2 >> cBits;
468 pResult->QWords.qw2 |= pValue->QWords.qw3 << (64 - cBits);
469 pResult->QWords.qw3 = pValue->QWords.qw3 >> cBits;
470 }
471 else
472 {
473 cBits -= 64;
474 pResult->QWords.qw0 = pValue->QWords.qw1 >> cBits;
475 pResult->QWords.qw0 |= pValue->QWords.qw2 << (64 - cBits);
476 pResult->QWords.qw1 = pValue->QWords.qw2 >> cBits;
477 pResult->QWords.qw1 |= pValue->QWords.qw3 << (64 - cBits);
478 pResult->QWords.qw2 = pValue->QWords.qw3 >> cBits;
479 pResult->QWords.qw3 = 0;
480 }
481 }
[52335]482 else
483 {
[94511]484 if (cBits < 192)
485 {
486 cBits -= 128;
487 pResult->QWords.qw0 = pValue->QWords.qw2 >> cBits;
488 pResult->QWords.qw0 |= pValue->QWords.qw3 << (64 - cBits);
489 pResult->QWords.qw1 = pValue->QWords.qw3 >> cBits;
490 pResult->QWords.qw2 = 0;
491 pResult->QWords.qw3 = 0;
492 }
493 else
494 {
495 cBits -= 192;
496 pResult->QWords.qw0 = pValue->QWords.qw3 >> cBits;
497 pResult->QWords.qw1 = 0;
498 pResult->QWords.qw2 = 0;
499 pResult->QWords.qw3 = 0;
500 }
[52335]501 }
502 return pResult;
503}
504
505
506/**
507 * Boolean not (result 0 or 1).
508 *
509 * @returns pResult.
510 * @param pResult The result variable.
511 * @param pValue The value.
512 */
[94511]513DECLINLINE(PRTUINT256U) RTUInt256BooleanNot(PRTUINT256U pResult, PCRTUINT256U pValue)
[52335]514{
[94511]515 pResult->QWords.qw0 = RTUInt256IsZero(pValue);
516 pResult->QWords.qw1 = 0;
517 pResult->QWords.qw2 = 0;
518 pResult->QWords.qw3 = 0;
[52335]519 return pResult;
520}
521
522
523/**
[94511]524 * Bitwise not (flips each bit of the 256 bits).
[52335]525 *
526 * @returns pResult.
527 * @param pResult The result variable.
528 * @param pValue The value.
529 */
[94511]530DECLINLINE(PRTUINT256U) RTUInt256BitwiseNot(PRTUINT256U pResult, PCRTUINT256U pValue)
[52335]531{
[94511]532 pResult->QWords.qw0 = ~pValue->QWords.qw0;
533 pResult->QWords.qw1 = ~pValue->QWords.qw1;
534 pResult->QWords.qw2 = ~pValue->QWords.qw2;
535 pResult->QWords.qw3 = ~pValue->QWords.qw3;
[52335]536 return pResult;
537}
538
539
540/**
[94511]541 * Assigns one 256-bit unsigned integer value to another.
[35488]542 *
543 * @returns pResult
544 * @param pResult The result variable.
545 * @param pValue The value to assign.
546 */
[94511]547DECLINLINE(PRTUINT256U) RTUInt256Assign(PRTUINT256U pResult, PCRTUINT256U pValue)
[35488]548{
[94511]549 pResult->QWords.qw0 = pValue->QWords.qw0;
550 pResult->QWords.qw1 = pValue->QWords.qw1;
551 pResult->QWords.qw2 = pValue->QWords.qw2;
552 pResult->QWords.qw3 = pValue->QWords.qw3;
[35488]553 return pResult;
554}
555
556
557/**
[94511]558 * Assigns a boolean value to 256-bit unsigned integer.
[35488]559 *
[57944]560 * @returns pValueResult
561 * @param pValueResult The result variable.
[35488]562 * @param fValue The boolean value.
563 */
[94511]564DECLINLINE(PRTUINT256U) RTUInt256AssignBoolean(PRTUINT256U pValueResult, bool fValue)
[35488]565{
[94511]566 pValueResult->QWords.qw0 = fValue;
567 pValueResult->QWords.qw1 = 0;
568 pValueResult->QWords.qw2 = 0;
569 pValueResult->QWords.qw3 = 0;
[35488]570 return pValueResult;
571}
572
573
574/**
[94511]575 * Assigns a 8-bit unsigned integer value to 256-bit unsigned integer.
[35488]576 *
[57944]577 * @returns pValueResult
578 * @param pValueResult The result variable.
[35488]579 * @param u8Value The 8-bit unsigned integer value.
580 */
[94511]581DECLINLINE(PRTUINT256U) RTUInt256AssignU8(PRTUINT256U pValueResult, uint8_t u8Value)
[35488]582{
[94511]583 pValueResult->QWords.qw0 = u8Value;
584 pValueResult->QWords.qw1 = 0;
585 pValueResult->QWords.qw2 = 0;
586 pValueResult->QWords.qw3 = 0;
[35488]587 return pValueResult;
588}
589
590
591/**
[94511]592 * Assigns a 16-bit unsigned integer value to 256-bit unsigned integer.
[35488]593 *
[57944]594 * @returns pValueResult
595 * @param pValueResult The result variable.
[35488]596 * @param u16Value The 16-bit unsigned integer value.
597 */
[94511]598DECLINLINE(PRTUINT256U) RTUInt256AssignU16(PRTUINT256U pValueResult, uint16_t u16Value)
[35488]599{
[94511]600 pValueResult->QWords.qw0 = u16Value;
601 pValueResult->QWords.qw1 = 0;
602 pValueResult->QWords.qw2 = 0;
603 pValueResult->QWords.qw3 = 0;
[35488]604 return pValueResult;
605}
606
607
608/**
[94511]609 * Assigns a 32-bit unsigned integer value to 256-bit unsigned integer.
[35488]610 *
[57944]611 * @returns pValueResult
612 * @param pValueResult The result variable.
[35488]613 * @param u32Value The 32-bit unsigned integer value.
614 */
[94511]615DECLINLINE(PRTUINT256U) RTUInt256AssignU32(PRTUINT256U pValueResult, uint32_t u32Value)
[35488]616{
[94511]617 pValueResult->QWords.qw0 = u32Value;
618 pValueResult->QWords.qw1 = 0;
619 pValueResult->QWords.qw2 = 0;
620 pValueResult->QWords.qw3 = 0;
[35488]621 return pValueResult;
622}
623
624
625/**
[94511]626 * Assigns a 64-bit unsigned integer value to 256-bit unsigned integer.
[35488]627 *
[57944]628 * @returns pValueResult
629 * @param pValueResult The result variable.
630 * @param u64Value The 64-bit unsigned integer value.
[35488]631 */
[94511]632DECLINLINE(PRTUINT256U) RTUInt256AssignU64(PRTUINT256U pValueResult, uint64_t u64Value)
[35488]633{
[94511]634 pValueResult->QWords.qw0 = u64Value;
635 pValueResult->QWords.qw1 = 0;
636 pValueResult->QWords.qw2 = 0;
637 pValueResult->QWords.qw3 = 0;
[35488]638 return pValueResult;
639}
640
641
[52335]642/**
[94511]643 * Adds two 256-bit unsigned integer values, storing the result in the first.
[52335]644 *
645 * @returns pValue1Result.
646 * @param pValue1Result The first value and result.
647 * @param pValue2 The second value.
648 */
[94511]649DECLINLINE(PRTUINT256U) RTUInt256AssignAdd(PRTUINT256U pValue1Result, PCRTUINT256U pValue2)
[52335]650{
[94511]651 RTUINT256U const uTmpValue1 = *pValue1Result; /* lazy bird */
652 return RTUInt256Add(pValue1Result, &uTmpValue1, pValue2);
[52335]653}
[35488]654
655
656/**
[94511]657 * Adds a 64-bit unsigned integer value to a 256-bit unsigned integer values,
658 * storing the result in the 256-bit one.
[52335]659 *
660 * @returns pValue1Result.
661 * @param pValue1Result The first value and result.
662 * @param uValue2 The second value, 64-bit.
663 */
[94511]664DECLINLINE(PRTUINT256U) RTUInt256AssignAddU64(PRTUINT256U pValue1Result, uint64_t uValue2)
[52335]665{
[94511]666 RTUINT256U const uTmpValue1 = *pValue1Result; /* lazy bird */
667 return RTUInt256AddU64(pValue1Result, &uTmpValue1, uValue2);
[52335]668}
669
670
671/**
[94511]672 * Subtracts two 256-bit unsigned integer values, storing the result in the
[52335]673 * first.
674 *
675 * @returns pValue1Result.
676 * @param pValue1Result The minuend value and result.
677 * @param pValue2 The subtrahend value.
678 */
[94511]679DECLINLINE(PRTUINT256U) RTUInt256AssignSub(PRTUINT256U pValue1Result, PCRTUINT256U pValue2)
[52335]680{
[94511]681 RTUINT256U const uTmpValue1 = *pValue1Result; /* lazy bird */
682 return RTUInt256Sub(pValue1Result, &uTmpValue1, pValue2);
[52335]683}
684
685
[94511]686#if 0
[52335]687/**
[94511]688 * Negates a 256 number, storing the result in the input.
[62401]689 *
690 * @returns pValueResult.
691 * @param pValueResult The value to negate.
692 */
[94511]693DECLINLINE(PRTUINT256U) RTUInt256AssignNeg(PRTUINT256U pValueResult)
[62401]694{
695 /* result = 0 - value */
[62403]696 if (pValueResult->s.Lo != 0)
[62401]697 {
[62403]698 pValueResult->s.Lo = UINT64_C(0) - pValueResult->s.Lo;
699 pValueResult->s.Hi = UINT64_MAX - pValueResult->s.Hi;
[62401]700 }
701 else
[62403]702 pValueResult->s.Hi = UINT64_C(0) - pValueResult->s.Hi;
703 return pValueResult;
[62401]704}
[94511]705#endif
[62401]706
707
708/**
[94511]709 * Multiplies two 256-bit unsigned integer values, storing the result in the
[52335]710 * first.
711 *
712 * @returns pValue1Result.
713 * @param pValue1Result The first value and result.
714 * @param pValue2 The second value.
715 */
[94511]716DECLINLINE(PRTUINT256U) RTUInt256AssignMul(PRTUINT256U pValue1Result, PCRTUINT256U pValue2)
[52335]717{
[94511]718 RTUINT256U Result;
719 RTUInt256Mul(&Result, pValue1Result, pValue2);
[52335]720 *pValue1Result = Result;
721 return pValue1Result;
722}
723
724
725/**
[94511]726 * Divides a 256-bit unsigned integer value by another, storing the result in
[52335]727 * the first.
728 *
729 * @returns pValue1Result.
730 * @param pValue1Result The dividend value and result.
731 * @param pValue2 The divisor value.
732 */
[94511]733DECLINLINE(PRTUINT256U) RTUInt256AssignDiv(PRTUINT256U pValue1Result, PCRTUINT256U pValue2)
[52335]734{
[94511]735 RTUINT256U Result;
736 RTUINT256U Ignored;
737 RTUInt256DivRem(&Result, &Ignored, pValue1Result, pValue2);
[52335]738 *pValue1Result = Result;
739 return pValue1Result;
740}
741
742
743/**
[94511]744 * Divides a 256-bit unsigned integer value by another, storing the remainder in
[52335]745 * the first.
746 *
747 * @returns pValue1Result.
748 * @param pValue1Result The dividend value and result (remainder).
749 * @param pValue2 The divisor value.
750 */
[94511]751DECLINLINE(PRTUINT256U) RTUInt256AssignMod(PRTUINT256U pValue1Result, PCRTUINT256U pValue2)
[52335]752{
[94511]753 RTUINT256U Ignored;
754 RTUINT256U Result;
755 RTUInt256DivRem(&Ignored, &Result, pValue1Result, pValue2);
[52335]756 *pValue1Result = Result;
757 return pValue1Result;
758}
759
760
761/**
[94511]762 * Performs a bitwise AND of two 256-bit unsigned integer values and assigned
[35488]763 * the result to the first one.
764 *
765 * @returns pValue1Result.
766 * @param pValue1Result The first value and result.
767 * @param pValue2 The second value.
768 */
[94511]769DECLINLINE(PRTUINT256U) RTUInt256AssignAnd(PRTUINT256U pValue1Result, PCRTUINT256U pValue2)
[35488]770{
[94511]771 pValue1Result->QWords.qw0 &= pValue2->QWords.qw0;
772 pValue1Result->QWords.qw1 &= pValue2->QWords.qw1;
773 pValue1Result->QWords.qw2 &= pValue2->QWords.qw2;
774 pValue1Result->QWords.qw3 &= pValue2->QWords.qw3;
[35488]775 return pValue1Result;
776}
777
778
[94511]779#if 0
[35488]780/**
[94511]781 * Performs a bitwise AND of a 256-bit unsigned integer value and a mask made
782 * up of the first N bits, assigning the result to the the 256-bit value.
[35490]783 *
784 * @returns pValueResult.
785 * @param pValueResult The value and result.
786 * @param cBits The number of bits to AND (counting from the first
787 * bit).
788 */
[94511]789DECLINLINE(PRTUINT256U) RTUInt256AssignAndNFirstBits(PRTUINT256U pValueResult, unsigned cBits)
[35490]790{
791 if (cBits <= 64)
792 {
793 if (cBits != 64)
794 pValueResult->s.Lo &= (RT_BIT_64(cBits) - 1);
795 pValueResult->s.Hi = 0;
796 }
[94511]797 else if (cBits < 256)
[35490]798 pValueResult->s.Hi &= (RT_BIT_64(cBits - 64) - 1);
[57978]799/** @todo \#if ARCH_BITS >= 64 */
[35490]800 return pValueResult;
801}
[94511]802#endif
[35490]803
804
805/**
[94511]806 * Performs a bitwise OR of two 256-bit unsigned integer values and assigned
[35488]807 * the result to the first one.
808 *
809 * @returns pValue1Result.
810 * @param pValue1Result The first value and result.
811 * @param pValue2 The second value.
812 */
[94511]813DECLINLINE(PRTUINT256U) RTUInt256AssignOr(PRTUINT256U pValue1Result, PCRTUINT256U pValue2)
[35488]814{
[94511]815 pValue1Result->QWords.qw0 |= pValue2->QWords.qw0;
816 pValue1Result->QWords.qw1 |= pValue2->QWords.qw1;
817 pValue1Result->QWords.qw2 |= pValue2->QWords.qw2;
818 pValue1Result->QWords.qw3 |= pValue2->QWords.qw3;
[35488]819 return pValue1Result;
820}
821
822
[94511]823DECLINLINE(PRTUINT256U) RTUInt256BitSet(PRTUINT256U pValueResult, unsigned iBit);
824
[35488]825/**
[52335]826 * ORs in a bit and assign the result to the input value.
827 *
828 * @returns pValue1Result.
829 * @param pValue1Result The first value and result.
830 * @param iBit The bit to set (0 based).
831 */
[94511]832DECLINLINE(PRTUINT256U) RTUInt256AssignOrBit(PRTUINT256U pValue1Result, uint32_t iBit)
[52335]833{
[94511]834 return RTUInt256BitSet(pValue1Result, (unsigned)iBit);
[52335]835}
836
837
838/**
[94511]839 * Performs a bitwise XOR of two 256-bit unsigned integer values and assigned
[35488]840 * the result to the first one.
841 *
842 * @returns pValue1Result.
843 * @param pValue1Result The first value and result.
844 * @param pValue2 The second value.
845 */
[94511]846DECLINLINE(PRTUINT256U) RTUInt256AssignXor(PRTUINT256U pValue1Result, PCRTUINT256U pValue2)
[35488]847{
[94511]848 pValue1Result->QWords.qw0 ^= pValue2->QWords.qw0;
849 pValue1Result->QWords.qw1 ^= pValue2->QWords.qw1;
850 pValue1Result->QWords.qw2 ^= pValue2->QWords.qw2;
851 pValue1Result->QWords.qw3 ^= pValue2->QWords.qw3;
[35488]852 return pValue1Result;
853}
854
855
856/**
[94511]857 * Performs a bitwise left shift on a 256-bit unsigned integer value, assigning
[35488]858 * the result to it.
859 *
[57944]860 * @returns pValueResult.
861 * @param pValueResult The first value and result.
[94511]862 * @param cBits The number of bits to shift - signed. Negative
863 * values are translated to right shifts. If the
864 * absolute value is 256 or higher, the value is set to
865 * zero.
866 *
867 * @note This works differently from RTUInt256ShiftLeft and
868 * RTUInt256ShiftRight in that the shift count is signed and not masked
869 * by 255.
[35488]870 */
[94511]871DECLINLINE(PRTUINT256U) RTUInt256AssignShiftLeft(PRTUINT256U pValueResult, int cBits)
[35488]872{
[94511]873 if (cBits == 0)
874 return pValueResult;
[35488]875 if (cBits > 0)
876 {
877 /* (left shift) */
[94511]878 if (cBits < 256)
[35488]879 {
[94511]880 RTUINT256U const InVal = *pValueResult;
881 return RTUInt256ShiftLeft(pValueResult, &InVal, cBits);
[35488]882 }
883 }
[94511]884 else if (cBits > -256)
[35488]885 {
886 /* (right shift) */
887 cBits = -cBits;
[94511]888 RTUINT256U const InVal = *pValueResult;
889 return RTUInt256ShiftRight(pValueResult, &InVal, cBits);
[35488]890 }
[94511]891 return RTUInt256SetZero(pValueResult);
[35488]892}
893
894
895/**
[94511]896 * Performs a bitwise left shift on a 256-bit unsigned integer value, assigning
[35488]897 * the result to it.
898 *
[57944]899 * @returns pValueResult.
900 * @param pValueResult The first value and result.
[94511]901 * @param cBits The number of bits to shift - signed. Negative
902 * values are translated to left shifts. If the
903 * absolute value is 256 or higher, the value is set to
904 * zero.
905 *
906 * @note This works differently from RTUInt256ShiftRight and
907 * RTUInt256ShiftLeft in that the shift count is signed and not masked
908 * by 255.
[35488]909 */
[94511]910DECLINLINE(PRTUINT256U) RTUInt256AssignShiftRight(PRTUINT256U pValueResult, int cBits)
[35488]911{
[94511]912 if (cBits == 0)
913 return pValueResult;
914 if (cBits > 0)
915 {
916 /* (right shift) */
917 if (cBits < 256)
918 {
919 RTUINT256U const InVal = *pValueResult;
920 return RTUInt256ShiftRight(pValueResult, &InVal, cBits);
921 }
922 }
923 else if (cBits > -256)
924 {
925 /* (left shift) */
926 cBits = -cBits;
927 RTUINT256U const InVal = *pValueResult;
928 return RTUInt256ShiftLeft(pValueResult, &InVal, cBits);
929 }
930 return RTUInt256SetZero(pValueResult);
[35488]931}
932
933
934/**
[94511]935 * Performs a bitwise NOT on a 256-bit unsigned integer value, assigning the
[35488]936 * result to it.
937 *
938 * @returns pValueResult
939 * @param pValueResult The value and result.
940 */
[94511]941DECLINLINE(PRTUINT256U) RTUInt256AssignBitwiseNot(PRTUINT256U pValueResult)
[35488]942{
[94511]943 pValueResult->QWords.qw0 = ~pValueResult->QWords.qw0;
944 pValueResult->QWords.qw1 = ~pValueResult->QWords.qw1;
945 pValueResult->QWords.qw2 = ~pValueResult->QWords.qw2;
946 pValueResult->QWords.qw3 = ~pValueResult->QWords.qw3;
[35488]947 return pValueResult;
948}
949
950
951/**
[94511]952 * Performs a boolean NOT on a 256-bit unsigned integer value, assigning the
[35488]953 * result to it.
954 *
955 * @returns pValueResult
956 * @param pValueResult The value and result.
957 */
[94511]958DECLINLINE(PRTUINT256U) RTUInt256AssignBooleanNot(PRTUINT256U pValueResult)
[35488]959{
[94511]960 return RTUInt256AssignBoolean(pValueResult, RTUInt256IsZero(pValueResult));
[35488]961}
962
963
964/**
[94511]965 * Compares two 256-bit unsigned integer values.
[35488]966 *
967 * @retval 0 if equal.
968 * @retval -1 if the first value is smaller than the second.
969 * @retval 1 if the first value is larger than the second.
970 *
971 * @param pValue1 The first value.
972 * @param pValue2 The second value.
973 */
[94511]974DECLINLINE(int) RTUInt256Compare(PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[35488]975{
[94511]976 if (pValue1->QWords.qw3 != pValue2->QWords.qw3)
977 return pValue1->QWords.qw3 > pValue2->QWords.qw3 ? 1 : -1;
978 if (pValue1->QWords.qw2 != pValue2->QWords.qw2)
979 return pValue1->QWords.qw2 > pValue2->QWords.qw2 ? 1 : -1;
980 if (pValue1->QWords.qw1 != pValue2->QWords.qw1)
981 return pValue1->QWords.qw1 > pValue2->QWords.qw1 ? 1 : -1;
982 if (pValue1->QWords.qw0 != pValue2->QWords.qw0)
983 return pValue1->QWords.qw3 > pValue2->QWords.qw3 ? 1 : -1;
[35488]984 return 0;
985}
986
987
988/**
[94511]989 * Tests if a 256-bit unsigned integer value is smaller than another.
[52335]990 *
991 * @returns true if the first value is smaller, false if not.
992 * @param pValue1 The first value.
993 * @param pValue2 The second value.
994 */
[94511]995DECLINLINE(bool) RTUInt256IsSmaller(PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]996{
[94511]997 return pValue1->QWords.qw3 < pValue2->QWords.qw3
998 || ( pValue1->QWords.qw3 == pValue2->QWords.qw3
999 && ( pValue1->QWords.qw2 < pValue2->QWords.qw2
1000 || ( pValue1->QWords.qw2 == pValue2->QWords.qw2
1001 && ( pValue1->QWords.qw1 < pValue2->QWords.qw1
1002 || ( pValue1->QWords.qw1 == pValue2->QWords.qw1
1003 && pValue1->QWords.qw0 < pValue2->QWords.qw0)))));
[52335]1004}
1005
1006
1007/**
[94511]1008 * Tests if a 256-bit unsigned integer value is larger than another.
[52335]1009 *
1010 * @returns true if the first value is larger, false if not.
1011 * @param pValue1 The first value.
1012 * @param pValue2 The second value.
1013 */
[94511]1014DECLINLINE(bool) RTUInt256IsLarger(PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]1015{
[94511]1016 return pValue1->QWords.qw3 > pValue2->QWords.qw3
1017 || ( pValue1->QWords.qw3 == pValue2->QWords.qw3
1018 && ( pValue1->QWords.qw2 > pValue2->QWords.qw2
1019 || ( pValue1->QWords.qw2 == pValue2->QWords.qw2
1020 && ( pValue1->QWords.qw1 > pValue2->QWords.qw1
1021 || ( pValue1->QWords.qw1 == pValue2->QWords.qw1
1022 && pValue1->QWords.qw0 > pValue2->QWords.qw0)))));
[52335]1023}
1024
1025
1026/**
[94511]1027 * Tests if a 256-bit unsigned integer value is larger or equal than another.
[52335]1028 *
1029 * @returns true if the first value is larger or equal, false if not.
1030 * @param pValue1 The first value.
1031 * @param pValue2 The second value.
1032 */
[94511]1033DECLINLINE(bool) RTUInt256IsLargerOrEqual(PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[52335]1034{
[94511]1035 return pValue1->QWords.qw3 > pValue2->QWords.qw3
1036 || ( pValue1->QWords.qw3 == pValue2->QWords.qw3
1037 && ( pValue1->QWords.qw2 > pValue2->QWords.qw2
1038 || ( pValue1->QWords.qw2 == pValue2->QWords.qw2
1039 && ( pValue1->QWords.qw1 > pValue2->QWords.qw1
1040 || ( pValue1->QWords.qw1 == pValue2->QWords.qw1
1041 && pValue1->QWords.qw0 >= pValue2->DWords.dw0)))));
[52335]1042}
1043
1044
1045/**
[94511]1046 * Tests if two 256-bit unsigned integer values not equal.
[35488]1047 *
1048 * @returns true if equal, false if not equal.
1049 * @param pValue1 The first value.
1050 * @param pValue2 The second value.
1051 */
[94511]1052DECLINLINE(bool) RTUInt256IsEqual(PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[35488]1053{
[94511]1054 return pValue1->QWords.qw0 == pValue2->QWords.qw0
1055 && pValue1->QWords.qw1 == pValue2->QWords.qw1
1056 && pValue1->QWords.qw2 == pValue2->QWords.qw2
1057 && pValue1->QWords.qw3 == pValue2->QWords.qw3;
[35488]1058}
1059
1060
1061/**
[94511]1062 * Tests if two 256-bit unsigned integer values are not equal.
[35488]1063 *
1064 * @returns true if not equal, false if equal.
1065 * @param pValue1 The first value.
1066 * @param pValue2 The second value.
1067 */
[94511]1068DECLINLINE(bool) RTUInt256IsNotEqual(PCRTUINT256U pValue1, PCRTUINT256U pValue2)
[35488]1069{
[94511]1070 return !RTUInt256IsEqual(pValue1, pValue2);
[35488]1071}
1072
1073
1074/**
[94511]1075 * Sets a bit in a 256-bit unsigned integer type.
[35488]1076 *
1077 * @returns pValueResult.
1078 * @param pValueResult The input and output value.
1079 * @param iBit The bit to set.
1080 */
[94511]1081DECLINLINE(PRTUINT256U) RTUInt256BitSet(PRTUINT256U pValueResult, unsigned iBit)
[35488]1082{
[94511]1083 if (iBit < 256)
[35488]1084 {
[94511]1085 unsigned idxQWord = iBit >> 6;
1086#ifdef RT_BIG_ENDIAN
1087 idxQWord = RT_ELEMENTS(pValueResult->au64) - idxQWord;
[35488]1088#endif
[94511]1089 iBit &= 0x3f;
1090 pValueResult->au64[idxQWord] |= RT_BIT_64(iBit);
[35488]1091 }
1092 return pValueResult;
1093}
1094
1095
1096/**
[94511]1097 * Sets a bit in a 256-bit unsigned integer type.
[35488]1098 *
1099 * @returns pValueResult.
1100 * @param pValueResult The input and output value.
1101 * @param iBit The bit to set.
1102 */
[94511]1103DECLINLINE(PRTUINT256U) RTUInt256BitClear(PRTUINT256U pValueResult, unsigned iBit)
[35488]1104{
[94511]1105 if (iBit < 256)
[35488]1106 {
[94511]1107 unsigned idxQWord = iBit >> 6;
1108#ifdef RT_BIG_ENDIAN
1109 idxQWord = RT_ELEMENTS(pValueResult->au64) - idxQWord;
[35488]1110#endif
[94511]1111 iBit &= 0x3f;
1112 pValueResult->au64[idxQWord] &= ~RT_BIT_64(iBit);
[35488]1113 }
1114 return pValueResult;
1115}
1116
1117
1118/**
[94511]1119 * Tests if a bit in a 256-bit unsigned integer value is set.
[35488]1120 *
1121 * @returns pValueResult.
1122 * @param pValueResult The input and output value.
1123 * @param iBit The bit to test.
1124 */
[94511]1125DECLINLINE(bool) RTUInt256BitTest(PRTUINT256U pValueResult, unsigned iBit)
[35488]1126{
1127 bool fRc;
[94511]1128 if (iBit < 256)
[35488]1129 {
[94511]1130 unsigned idxQWord = iBit >> 6;
1131#ifdef RT_BIG_ENDIAN
1132 idxQWord = RT_ELEMENTS(pValueResult->au64) - idxQWord;
[35488]1133#endif
[94511]1134 iBit &= 0x3f;
1135 fRc = RT_BOOL(pValueResult->au64[idxQWord] & RT_BIT_64(iBit));
[35488]1136 }
1137 else
1138 fRc = false;
1139 return fRc;
1140}
1141
1142
1143/**
[94511]1144 * Set a range of bits a 256-bit unsigned integer value.
[35488]1145 *
1146 * @returns pValueResult.
1147 * @param pValueResult The input and output value.
1148 * @param iFirstBit The first bit to test.
1149 * @param cBits The number of bits to set.
1150 */
[94511]1151DECLINLINE(PRTUINT256U) RTUInt256BitSetRange(PRTUINT256U pValueResult, unsigned iFirstBit, unsigned cBits)
[35488]1152{
1153 /* bounds check & fix. */
[94511]1154 if (iFirstBit < 256)
[35488]1155 {
[94511]1156 if (iFirstBit + cBits > 256)
1157 cBits = 256 - iFirstBit;
[35488]1158
[94511]1159 /* Work the au64 array: */
1160#ifdef RT_BIG_ENDIAN
1161 int idxQWord = RT_ELEMENTS(pValueResult->au64) - (iFirstBit >> 6);
1162 int const idxInc = -1;
[35488]1163#else
[94511]1164 int idxQWord = iFirstBit >> 6;
1165 int const idxInc = 1;
[35488]1166#endif
[94511]1167 while (cBits > 0)
1168 {
1169 unsigned iQWordFirstBit = iFirstBit & 0x3f;
1170 unsigned cQWordBits = cBits + iQWordFirstBit >= 64 ? 64 - iQWordFirstBit : cBits;
1171 pValueResult->au64[idxQWord] |= cQWordBits < 64 ? (RT_BIT_64(cQWordBits) - 1) << iQWordFirstBit : UINT64_MAX;
1172
1173 idxQWord += idxInc;
1174 iFirstBit += cQWordBits;
1175 cBits -= cQWordBits;
1176 }
[35488]1177 }
1178 return pValueResult;
1179}
1180
1181
1182/**
[94511]1183 * Test if all the bits of a 256-bit unsigned integer value are set.
[35488]1184 *
1185 * @returns true if they are, false if they aren't.
1186 * @param pValue The input and output value.
1187 */
[94511]1188DECLINLINE(bool) RTUInt256BitAreAllSet(PRTUINT256U pValue)
[35488]1189{
[94511]1190 return pValue->QWords.qw0 == UINT64_MAX
1191 && pValue->QWords.qw1 == UINT64_MAX
1192 && pValue->QWords.qw2 == UINT64_MAX
1193 && pValue->QWords.qw3 == UINT64_MAX;
[35488]1194}
1195
1196
1197/**
[94511]1198 * Test if all the bits of a 256-bit unsigned integer value are clear.
[35488]1199 *
1200 * @returns true if they are, false if they aren't.
1201 * @param pValue The input and output value.
1202 */
[94511]1203DECLINLINE(bool) RTUInt256BitAreAllClear(PRTUINT256U pValue)
[35488]1204{
[94511]1205 return RTUInt256IsZero(pValue);
[35488]1206}
1207
[52335]1208
1209/**
[94511]1210 * Number of significant bits in the value.
[52335]1211 *
[94511]1212 * This is the same a ASMBitLastSetU64 and ASMBitLastSetU32.
1213 *
1214 * @returns 0 if zero, 1-base index of the last bit set.
1215 * @param pValue The value to examine.
[52335]1216 */
[94511]1217DECLINLINE(uint32_t) RTUInt256BitCount(PCRTUINT256U pValue)
[52335]1218{
[94511]1219 uint64_t u64;
1220 uint32_t cBits;
1221 if ((u64 = pValue->QWords.qw3) != 0)
1222 cBits = 192;
1223 else if ((u64 = pValue->QWords.qw2) != 0)
1224 cBits = 128;
1225 else if ((u64 = pValue->QWords.qw1) != 0)
1226 cBits = 64;
[52335]1227 else
1228 {
[94511]1229 u64 = pValue->QWords.qw0;
1230 cBits = 0;
[52335]1231 }
[94511]1232 return cBits + ASMBitLastSetU64(u64);
[52335]1233}
1234
1235
[35488]1236/** @} */
1237
1238RT_C_DECLS_END
1239
[94511]1240#endif /* !IPRT_INCLUDED_uint256_h */
[35488]1241
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use