VirtualBox

source: vbox/trunk/include/iprt/uint32.h@ 76553

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

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.9 KB
Line 
1/** @file
2 * IPRT - RTUINT32U methods for old 16-bit compilers (mainly for division).
3 */
4
5/*
6 * Copyright (C) 2011-2019 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_uint32_h
27#define ___iprt_uint32_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/cdefs.h>
33#include <iprt/types.h>
34#include <iprt/asm.h>
35
36RT_C_DECLS_BEGIN
37
38/** @defgroup grp_rt_uint32 RTUInt32 - 32-bit Unsigned Integer Methods for 16-bit compilers.
39 * @ingroup grp_rt
40 * @{
41 */
42
43#define RTUINT32_HAVE_32BIT_BASICS
44
45
46/**
47 * Test if a 32-bit unsigned integer value is zero.
48 *
49 * @returns true if they are, false if they aren't.
50 * @param pValue The input and output value.
51 */
52DECLINLINE(bool) RTUInt32IsZero(PRTUINT32U pValue)
53{
54 return pValue->s.Lo == 0
55 && pValue->s.Hi == 0;
56}
57
58
59/**
60 * Set a 32-bit unsigned integer value to zero.
61 *
62 * @returns pResult
63 * @param pResult The result variable.
64 */
65DECLINLINE(PRTUINT32U) RTUInt32SetZero(PRTUINT32U pResult)
66{
67 pResult->s.Hi = 0;
68 pResult->s.Lo = 0;
69 return pResult;
70}
71
72
73/**
74 * Set a 32-bit unsigned integer value to the maximum value.
75 *
76 * @returns pResult
77 * @param pResult The result variable.
78 */
79DECLINLINE(PRTUINT32U) RTUInt32SetMax(PRTUINT32U pResult)
80{
81 pResult->s.Hi = UINT16_MAX;
82 pResult->s.Lo = UINT16_MAX;
83 return pResult;
84}
85
86
87
88
89/**
90 * Adds two 32-bit unsigned integer values.
91 *
92 * @returns pResult
93 * @param pResult The result variable.
94 * @param pValue1 The first value.
95 * @param pValue2 The second value.
96 */
97DECLINLINE(PRTUINT32U) RTUInt32Add(PRTUINT32U pResult, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
98{
99#ifdef RTUINT32_HAVE_32BIT_BASICS
100 pResult->u = pValue1->u + pValue2->u;
101#else
102 pResult->s.Hi = pValue1->s.Hi + pValue2->s.Hi;
103 pResult->s.Lo = pValue1->s.Lo + pValue2->s.Lo;
104 if (pResult->s.Lo < pValue1->s.Lo)
105 pResult->s.Hi++;
106#endif
107 return pResult;
108}
109
110
111/**
112 * Adds a 32-bit and a 16-bit unsigned integer values.
113 *
114 * @returns pResult
115 * @param pResult The result variable.
116 * @param pValue1 The first value.
117 * @param uValue2 The second value, 16-bit.
118 */
119DECLINLINE(PRTUINT32U) RTUInt32AddU16(PRTUINT32U pResult, PCRTUINT32U pValue1, uint16_t uValue2)
120{
121#ifdef RTUINT32_HAVE_32BIT_BASICS
122 pResult->u = pValue1->u + uValue2;
123#else
124 pResult->s.Hi = pValue1->s.Hi;
125 pResult->s.Lo = pValue1->s.Lo + uValue2;
126 if (pResult->s.Lo < pValue1->s.Lo)
127 pResult->s.Hi++;
128#endif
129 return pResult;
130}
131
132
133/**
134 * Subtracts a 32-bit unsigned integer value from another.
135 *
136 * @returns pResult
137 * @param pResult The result variable.
138 * @param pValue1 The minuend value.
139 * @param pValue2 The subtrahend value.
140 */
141DECLINLINE(PRTUINT32U) RTUInt32Sub(PRTUINT32U pResult, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
142{
143#ifdef RTUINT32_HAVE_32BIT_BASICS
144 pResult->u = pValue1->u - pValue2->u;
145#else
146 pResult->s.Lo = pValue1->s.Lo - pValue2->s.Lo;
147 pResult->s.Hi = pValue1->s.Hi - pValue2->s.Hi;
148 if (pResult->s.Lo > pValue1->s.Lo)
149 pResult->s.Hi--;
150#endif
151 return pResult;
152}
153
154
155/**
156 * Multiplies two 32-bit unsigned integer values.
157 *
158 * @returns pResult
159 * @param pResult The result variable.
160 * @param pValue1 The first value.
161 * @param pValue2 The second value.
162 */
163DECLINLINE(PRTUINT32U) RTUInt32Mul(PRTUINT32U pResult, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
164{
165 pResult->u = (uint32_t)pValue1->s.Lo * pValue2->s.Lo;
166 pResult->s.Hi += pValue1->s.Hi * pValue2->s.Lo;
167 pResult->s.Hi += pValue1->s.Lo * pValue2->s.Hi;
168
169 return pResult;
170}
171
172
173/**
174 * Multiplies an 32-bit unsigned integer by a 16-bit unsigned integer value.
175 *
176 * @returns pResult
177 * @param pResult The result variable.
178 * @param pValue1 The first value.
179 * @param uValue2 The second value, 16-bit.
180 */
181DECLINLINE(PRTUINT32U) RTUInt32MulByU16(PRTUINT32U pResult, PCRTUINT32U pValue1, uint16_t uValue2)
182{
183 pResult->u = (uint32_t)pValue1->s.Lo * uValue2;
184 pResult->s.Hi += pValue1->s.Hi * uValue2;
185 return pResult;
186}
187
188
189DECLINLINE(PRTUINT32U) RTUInt32DivRem(PRTUINT32U pQuotient, PRTUINT32U pRemainder, PCRTUINT32U pValue1, PCRTUINT32U pValue2);
190
191/**
192 * Divides a 32-bit unsigned integer value by another.
193 *
194 * @returns pResult
195 * @param pResult The result variable.
196 * @param pValue1 The dividend value.
197 * @param pValue2 The divisor value.
198 */
199DECLINLINE(PRTUINT32U) RTUInt32Div(PRTUINT32U pResult, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
200{
201 RTUINT32U Ignored;
202 return RTUInt32DivRem(pResult, &Ignored, pValue1, pValue2);
203}
204
205
206/**
207 * Divides a 32-bit unsigned integer value by another, returning the remainder.
208 *
209 * @returns pResult
210 * @param pResult The result variable (remainder).
211 * @param pValue1 The dividend value.
212 * @param pValue2 The divisor value.
213 */
214DECLINLINE(PRTUINT32U) RTUInt32Mod(PRTUINT32U pResult, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
215{
216 RTUINT32U Ignored;
217 RTUInt32DivRem(&Ignored, pResult, pValue1, pValue2);
218 return pResult;
219}
220
221
222/**
223 * Bitwise AND of two 32-bit unsigned integer values.
224 *
225 * @returns pResult
226 * @param pResult The result variable.
227 * @param pValue1 The first value.
228 * @param pValue2 The second value.
229 */
230DECLINLINE(PRTUINT32U) RTUInt32And(PRTUINT32U pResult, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
231{
232 pResult->s.Hi = pValue1->s.Hi & pValue2->s.Hi;
233 pResult->s.Lo = pValue1->s.Lo & pValue2->s.Lo;
234 return pResult;
235}
236
237
238/**
239 * Bitwise OR of two 32-bit unsigned integer values.
240 *
241 * @returns pResult
242 * @param pResult The result variable.
243 * @param pValue1 The first value.
244 * @param pValue2 The second value.
245 */
246DECLINLINE(PRTUINT32U) RTUInt32Or( PRTUINT32U pResult, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
247{
248 pResult->s.Hi = pValue1->s.Hi | pValue2->s.Hi;
249 pResult->s.Lo = pValue1->s.Lo | pValue2->s.Lo;
250 return pResult;
251}
252
253
254/**
255 * Bitwise XOR of two 32-bit unsigned integer values.
256 *
257 * @returns pResult
258 * @param pResult The result variable.
259 * @param pValue1 The first value.
260 * @param pValue2 The second value.
261 */
262DECLINLINE(PRTUINT32U) RTUInt32Xor(PRTUINT32U pResult, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
263{
264 pResult->s.Hi = pValue1->s.Hi ^ pValue2->s.Hi;
265 pResult->s.Lo = pValue1->s.Lo ^ pValue2->s.Lo;
266 return pResult;
267}
268
269
270/**
271 * Shifts a 32-bit unsigned integer value @a cBits to the left.
272 *
273 * @returns pResult
274 * @param pResult The result variable.
275 * @param pValue The value to shift.
276 * @param cBits The number of bits to shift it.
277 */
278DECLINLINE(PRTUINT32U) RTUInt32ShiftLeft(PRTUINT32U pResult, PCRTUINT32U pValue, int cBits)
279{
280 cBits &= 31;
281#ifdef RTUINT32_HAVE_32BIT_BASICS
282 pResult->u = pValue->u << cBits;
283#else
284 if (cBits < 16)
285 {
286 pResult->s.Lo = pValue->s.Lo << cBits;
287 pResult->s.Hi = (pValue->s.Hi << cBits) | (pValue->s.Lo >> (16 - cBits));
288 }
289 else
290 {
291 pResult->s.Lo = 0;
292 pResult->s.Hi = pValue->s.Lo << (cBits - 16);
293 }
294#endif
295 return pResult;
296}
297
298
299/**
300 * Shifts a 32-bit unsigned integer value @a cBits to the right.
301 *
302 * @returns pResult
303 * @param pResult The result variable.
304 * @param pValue The value to shift.
305 * @param cBits The number of bits to shift it.
306 */
307DECLINLINE(PRTUINT32U) RTUInt32ShiftRight(PRTUINT32U pResult, PCRTUINT32U pValue, int cBits)
308{
309 cBits &= 31;
310#ifdef RTUINT32_HAVE_32BIT_BASICS
311 pResult->u = pValue->u >> cBits;
312#else
313 if (cBits < 16)
314 {
315 pResult->s.Hi = pValue->s.Hi >> cBits;
316 pResult->s.Lo = (pValue->s.Lo >> cBits) | (pValue->s.Hi << (16 - cBits));
317 }
318 else
319 {
320 pResult->s.Hi = 0;
321 pResult->s.Lo = pValue->s.Hi >> (cBits - 16);
322 }
323#endif
324 return pResult;
325}
326
327
328/**
329 * Boolean not (result 0 or 1).
330 *
331 * @returns pResult.
332 * @param pResult The result variable.
333 * @param pValue The value.
334 */
335DECLINLINE(PRTUINT32U) RTUInt32BooleanNot(PRTUINT32U pResult, PCRTUINT32U pValue)
336{
337 pResult->s.Lo = pValue->s.Lo || pValue->s.Hi ? 0 : 1;
338 pResult->s.Hi = 0;
339 return pResult;
340}
341
342
343/**
344 * Bitwise not (flips each bit of the 32 bits).
345 *
346 * @returns pResult.
347 * @param pResult The result variable.
348 * @param pValue The value.
349 */
350DECLINLINE(PRTUINT32U) RTUInt32BitwiseNot(PRTUINT32U pResult, PCRTUINT32U pValue)
351{
352 pResult->s.Hi = ~pValue->s.Hi;
353 pResult->s.Lo = ~pValue->s.Lo;
354 return pResult;
355}
356
357
358/**
359 * Assigns one 32-bit unsigned integer value to another.
360 *
361 * @returns pResult
362 * @param pResult The result variable.
363 * @param pValue The value to assign.
364 */
365DECLINLINE(PRTUINT32U) RTUInt32Assign(PRTUINT32U pResult, PCRTUINT32U pValue)
366{
367 pResult->s.Hi = pValue->s.Hi;
368 pResult->s.Lo = pValue->s.Lo;
369 return pResult;
370}
371
372
373/**
374 * Assigns a boolean value to 32-bit unsigned integer.
375 *
376 * @returns pValueResult
377 * @param pValueResult The result variable.
378 * @param fValue The boolean value.
379 */
380DECLINLINE(PRTUINT32U) RTUInt32AssignBoolean(PRTUINT32U pValueResult, bool fValue)
381{
382 pValueResult->s.Lo = fValue;
383 pValueResult->s.Hi = 0;
384 return pValueResult;
385}
386
387
388/**
389 * Assigns a 8-bit unsigned integer value to 32-bit unsigned integer.
390 *
391 * @returns pValueResult
392 * @param pValueResult The result variable.
393 * @param u8Value The 8-bit unsigned integer value.
394 */
395DECLINLINE(PRTUINT32U) RTUInt32AssignU8(PRTUINT32U pValueResult, uint8_t u8Value)
396{
397 pValueResult->s.Lo = u8Value;
398 pValueResult->s.Hi = 0;
399 return pValueResult;
400}
401
402
403/**
404 * Assigns a 16-bit unsigned integer value to 32-bit unsigned integer.
405 *
406 * @returns pValueResult
407 * @param pValueResult The result variable.
408 * @param u16Value The 16-bit unsigned integer value.
409 */
410DECLINLINE(PRTUINT32U) RTUInt32AssignU16(PRTUINT32U pValueResult, uint16_t u16Value)
411{
412 pValueResult->s.Lo = u16Value;
413 pValueResult->s.Hi = 0;
414 return pValueResult;
415}
416
417
418/**
419 * Adds two 32-bit unsigned integer values, storing the result in the first.
420 *
421 * @returns pValue1Result.
422 * @param pValue1Result The first value and result.
423 * @param pValue2 The second value.
424 */
425DECLINLINE(PRTUINT32U) RTUInt32AssignAdd(PRTUINT32U pValue1Result, PCRTUINT32U pValue2)
426{
427#ifdef RTUINT32_HAVE_32BIT_BASICS
428 pValue1Result->u += pValue2->u;
429#else
430 uint16_t const uTmp = pValue1Result->s.Lo;
431 pValue1Result->s.Lo += pValue2->s.Lo;
432 if (pValue1Result->s.Lo < uTmp)
433 pValue1Result->s.Hi++;
434 pValue1Result->s.Hi += pValue2->s.Hi;
435#endif
436 return pValue1Result;
437}
438
439
440/**
441 * Subtracts two 32-bit unsigned integer values, storing the result in the
442 * first.
443 *
444 * @returns pValue1Result.
445 * @param pValue1Result The minuend value and result.
446 * @param pValue2 The subtrahend value.
447 */
448DECLINLINE(PRTUINT32U) RTUInt32AssignSub(PRTUINT32U pValue1Result, PCRTUINT32U pValue2)
449{
450#ifdef RTUINT32_HAVE_32BIT_BASICS
451 pValue1Result->u -= pValue2->u;
452#else
453 uint32_t const uTmp = pValue1Result->s.Lo;
454 pValue1Result->s.Lo -= pValue2->s.Lo;
455 if (pValue1Result->s.Lo > uTmp)
456 pValue1Result->s.Hi--;
457 pValue1Result->s.Hi -= pValue2->s.Hi;
458#endif
459 return pValue1Result;
460}
461
462
463/**
464 * Multiplies two 32-bit unsigned integer values, storing the result in the
465 * first.
466 *
467 * @returns pValue1Result.
468 * @param pValue1Result The first value and result.
469 * @param pValue2 The second value.
470 */
471DECLINLINE(PRTUINT32U) RTUInt32AssignMul(PRTUINT32U pValue1Result, PCRTUINT32U pValue2)
472{
473 RTUINT32U Result;
474 RTUInt32Mul(&Result, pValue1Result, pValue2);
475 *pValue1Result = Result;
476 return pValue1Result;
477}
478
479
480/**
481 * Divides a 32-bit unsigned integer value by another, storing the result in
482 * the first.
483 *
484 * @returns pValue1Result.
485 * @param pValue1Result The dividend value and result.
486 * @param pValue2 The divisor value.
487 */
488DECLINLINE(PRTUINT32U) RTUInt32AssignDiv(PRTUINT32U pValue1Result, PCRTUINT32U pValue2)
489{
490 RTUINT32U Result;
491 RTUINT32U Ignored;
492 RTUInt32DivRem(&Result, &Ignored, pValue1Result, pValue2);
493 *pValue1Result = Result;
494 return pValue1Result;
495}
496
497
498/**
499 * Divides a 32-bit unsigned integer value by another, storing the remainder in
500 * the first.
501 *
502 * @returns pValue1Result.
503 * @param pValue1Result The dividend value and result (remainder).
504 * @param pValue2 The divisor value.
505 */
506DECLINLINE(PRTUINT32U) RTUInt32AssignMod(PRTUINT32U pValue1Result, PCRTUINT32U pValue2)
507{
508 RTUINT32U Ignored;
509 RTUINT32U Result;
510 RTUInt32DivRem(&Ignored, &Result, pValue1Result, pValue2);
511 *pValue1Result = Result;
512 return pValue1Result;
513}
514
515
516/**
517 * Performs a bitwise AND of two 32-bit unsigned integer values and assigned
518 * the result to the first one.
519 *
520 * @returns pValue1Result.
521 * @param pValue1Result The first value and result.
522 * @param pValue2 The second value.
523 */
524DECLINLINE(PRTUINT32U) RTUInt32AssignAnd(PRTUINT32U pValue1Result, PCRTUINT32U pValue2)
525{
526 pValue1Result->s.Hi &= pValue2->s.Hi;
527 pValue1Result->s.Lo &= pValue2->s.Lo;
528 return pValue1Result;
529}
530
531
532/**
533 * Performs a bitwise AND of a 32-bit unsigned integer value and a mask made up
534 * of the first N bits, assigning the result to the the 32-bit value.
535 *
536 * @returns pValueResult.
537 * @param pValueResult The value and result.
538 * @param cBits The number of bits to AND (counting from the first
539 * bit).
540 */
541DECLINLINE(PRTUINT32U) RTUInt32AssignAndNFirstBits(PRTUINT32U pValueResult, unsigned cBits)
542{
543#ifdef RTUINT32_HAVE_32BIT_BASICS
544 if (cBits < 32)
545 pValueResult->u &= RT_BIT_32(cBits) - 1;
546#else
547 if (cBits <= 16)
548 {
549 if (cBits != 16)
550 pValueResult->s.Lo &= (UINT16_C(1) << cBits) - 1;
551 pValueResult->s.Hi = 0;
552 }
553 else if (cBits < 16)
554 pValueResult->s.Hi &= (UINT16_C(1) << (cBits - 16)) - 1;
555#endif
556 return pValueResult;
557}
558
559
560/**
561 * Performs a bitwise OR of two 32-bit unsigned integer values and assigned
562 * the result to the first one.
563 *
564 * @returns pValue1Result.
565 * @param pValue1Result The first value and result.
566 * @param pValue2 The second value.
567 */
568DECLINLINE(PRTUINT32U) RTUInt32AssignOr(PRTUINT32U pValue1Result, PCRTUINT32U pValue2)
569{
570 pValue1Result->s.Hi |= pValue2->s.Hi;
571 pValue1Result->s.Lo |= pValue2->s.Lo;
572 return pValue1Result;
573}
574
575
576/**
577 * ORs in a bit and assign the result to the input value.
578 *
579 * @returns pValue1Result.
580 * @param pValue1Result The first value and result.
581 * @param iBit The bit to set (0 based).
582 */
583DECLINLINE(PRTUINT32U) RTUInt32AssignOrBit(PRTUINT32U pValue1Result, unsigned iBit)
584{
585#ifdef RTUINT32_HAVE_32BIT_BASICS
586 pValue1Result->u |= RT_BIT_32(iBit);
587#else
588 if (iBit >= 32)
589 pValue1Result->s.Hi |= UINT16_C(1) << (iBit - 32);
590 else
591 pValue1Result->s.Lo |= UINT16_C(1) << iBit;
592#endif
593 return pValue1Result;
594}
595
596
597
598/**
599 * Performs a bitwise XOR of two 32-bit unsigned integer values and assigned
600 * the result to the first one.
601 *
602 * @returns pValue1Result.
603 * @param pValue1Result The first value and result.
604 * @param pValue2 The second value.
605 */
606DECLINLINE(PRTUINT32U) RTUInt32AssignXor(PRTUINT32U pValue1Result, PCRTUINT32U pValue2)
607{
608 pValue1Result->s.Hi ^= pValue2->s.Hi;
609 pValue1Result->s.Lo ^= pValue2->s.Lo;
610 return pValue1Result;
611}
612
613
614/**
615 * Performs a bitwise left shift on a 32-bit unsigned integer value, assigning
616 * the result to it.
617 *
618 * @returns pValueResult.
619 * @param pValueResult The first value and result.
620 * @param cBits The number of bits to shift.
621 */
622DECLINLINE(PRTUINT32U) RTUInt32AssignShiftLeft(PRTUINT32U pValueResult, int cBits)
623{
624#ifndef RTUINT32_HAVE_32BIT_BASICS
625 RTUINT32U const InVal = *pValueResult;
626#endif
627 if (cBits > 0)
628 {
629 /* (left shift) */
630 cBits &= 31;
631#ifdef RTUINT32_HAVE_32BIT_BASICS
632 pValueResult->u <<= cBits;
633#else
634 if (cBits >= 16)
635 {
636 pValueResult->s.Lo = 0;
637 pValueResult->s.Hi = InVal.s.Lo << (cBits - 16);
638 }
639 else
640 {
641 pValueResult->s.Hi = InVal.s.Hi << cBits;
642 pValueResult->s.Hi |= InVal.s.Lo >> (16 - cBits);
643 pValueResult->s.Lo = InVal.s.Lo << cBits;
644 }
645#endif
646 }
647 else if (cBits < 0)
648 {
649 /* (right shift) */
650 cBits = -cBits;
651 cBits &= 31;
652#ifdef RTUINT32_HAVE_32BIT_BASICS
653 pValueResult->u >>= cBits;
654#else
655 if (cBits >= 16)
656 {
657 pValueResult->s.Hi = 0;
658 pValueResult->s.Lo = InVal.s.Hi >> (cBits - 16);
659 }
660 else
661 {
662 pValueResult->s.Lo = InVal.s.Lo >> cBits;
663 pValueResult->s.Lo |= InVal.s.Hi << (16 - cBits);
664 pValueResult->s.Hi = InVal.s.Hi >> cBits;
665 }
666#endif
667 }
668 return pValueResult;
669}
670
671
672/**
673 * Performs a bitwise left shift on a 32-bit unsigned integer value, assigning
674 * the result to it.
675 *
676 * @returns pValueResult.
677 * @param pValueResult The first value and result.
678 * @param cBits The number of bits to shift.
679 */
680DECLINLINE(PRTUINT32U) RTUInt32AssignShiftRight(PRTUINT32U pValueResult, int cBits)
681{
682 return RTUInt32AssignShiftLeft(pValueResult, -cBits);
683}
684
685
686/**
687 * Performs a bitwise NOT on a 32-bit unsigned integer value, assigning the
688 * result to it.
689 *
690 * @returns pValueResult
691 * @param pValueResult The value and result.
692 */
693DECLINLINE(PRTUINT32U) RTUInt32AssignBitwiseNot(PRTUINT32U pValueResult)
694{
695 pValueResult->s.Hi = ~pValueResult->s.Hi;
696 pValueResult->s.Lo = ~pValueResult->s.Lo;
697 return pValueResult;
698}
699
700
701/**
702 * Performs a boolean NOT on a 32-bit unsigned integer value, assigning the
703 * result to it.
704 *
705 * @returns pValueResult
706 * @param pValueResult The value and result.
707 */
708DECLINLINE(PRTUINT32U) RTUInt32AssignBooleanNot(PRTUINT32U pValueResult)
709{
710 return RTUInt32AssignBoolean(pValueResult, RTUInt32IsZero(pValueResult));
711}
712
713
714/**
715 * Compares two 32-bit unsigned integer values.
716 *
717 * @retval 0 if equal.
718 * @retval -1 if the first value is smaller than the second.
719 * @retval 1 if the first value is larger than the second.
720 *
721 * @param pValue1 The first value.
722 * @param pValue2 The second value.
723 */
724DECLINLINE(int) RTUInt32Compare(PCRTUINT32U pValue1, PCRTUINT32U pValue2)
725{
726 if (pValue1->s.Hi != pValue2->s.Hi)
727 return pValue1->s.Hi > pValue2->s.Hi ? 1 : -1;
728 if (pValue1->s.Lo != pValue2->s.Lo)
729 return pValue1->s.Lo > pValue2->s.Lo ? 1 : -1;
730 return 0;
731}
732
733
734/**
735 * Tests if a 64-bit unsigned integer value is smaller than another.
736 *
737 * @returns true if the first value is smaller, false if not.
738 * @param pValue1 The first value.
739 * @param pValue2 The second value.
740 */
741DECLINLINE(bool) RTUInt32IsSmaller(PCRTUINT32U pValue1, PCRTUINT32U pValue2)
742{
743#ifdef RTUINT32_HAVE_32BIT_BASICS
744 return pValue1->u < pValue2->u;
745#else
746 return pValue1->s.Hi < pValue2->s.Hi
747 || ( pValue1->s.Hi == pValue2->s.Hi
748 && pValue1->s.Lo < pValue2->s.Lo);
749#endif
750}
751
752
753/**
754 * Tests if a 32-bit unsigned integer value is larger than another.
755 *
756 * @returns true if the first value is larger, false if not.
757 * @param pValue1 The first value.
758 * @param pValue2 The second value.
759 */
760DECLINLINE(bool) RTUInt32IsLarger(PCRTUINT32U pValue1, PCRTUINT32U pValue2)
761{
762#ifdef RTUINT32_HAVE_32BIT_BASICS
763 return pValue1->u > pValue2->u;
764#else
765 return pValue1->s.Hi > pValue2->s.Hi
766 || ( pValue1->s.Hi == pValue2->s.Hi
767 && pValue1->s.Lo > pValue2->s.Lo);
768#endif
769}
770
771
772/**
773 * Tests if a 64-bit unsigned integer value is larger or equal than another.
774 *
775 * @returns true if the first value is larger or equal, false if not.
776 * @param pValue1 The first value.
777 * @param pValue2 The second value.
778 */
779DECLINLINE(bool) RTUInt32IsLargerOrEqual(PCRTUINT32U pValue1, PCRTUINT32U pValue2)
780{
781#ifdef RTUINT32_HAVE_32BIT_BASICS
782 return pValue1->u >= pValue2->u;
783#else
784 return pValue1->s.Hi > pValue2->s.Hi
785 || ( pValue1->s.Hi == pValue2->s.Hi
786 && pValue1->s.Lo >= pValue2->s.Lo);
787#endif
788}
789
790
791/**
792 * Tests if two 64-bit unsigned integer values not equal.
793 *
794 * @returns true if equal, false if not equal.
795 * @param pValue1 The first value.
796 * @param pValue2 The second value.
797 */
798DECLINLINE(bool) RTUInt32IsEqual(PCRTUINT32U pValue1, PCRTUINT32U pValue2)
799{
800#ifdef RTUINT32_HAVE_32BIT_BASICS
801 return pValue1->u == pValue2->u;
802#else
803 return pValue1->s.Hi == pValue2->s.Hi
804 && pValue1->s.Lo == pValue2->s.Lo;
805#endif
806}
807
808
809/**
810 * Tests if two 64-bit unsigned integer values are not equal.
811 *
812 * @returns true if not equal, false if equal.
813 * @param pValue1 The first value.
814 * @param pValue2 The second value.
815 */
816DECLINLINE(bool) RTUInt32IsNotEqual(PCRTUINT32U pValue1, PCRTUINT32U pValue2)
817{
818 return !RTUInt32IsEqual(pValue1, pValue2);
819}
820
821
822/**
823 * Sets a bit in a 32-bit unsigned integer type.
824 *
825 * @returns pValueResult.
826 * @param pValueResult The input and output value.
827 * @param iBit The bit to set.
828 */
829DECLINLINE(PRTUINT32U) RTUInt32BitSet(PRTUINT32U pValueResult, unsigned iBit)
830{
831#ifdef RTUINT32_HAVE_32BIT_BASICS
832 if (iBit < 32)
833 pValueResult->u |= RT_BIT_32(iBit);
834#else
835 if (iBit < 16)
836 pValueResult->s.Lo |= UINT16_C(1) << iBit;
837 else if (iBit < 32)
838 pValueResult->s.Hi |= UINT16_C(1) << (iBit - 32);
839#endif
840 return pValueResult;
841}
842
843
844/**
845 * Sets a bit in a 32-bit unsigned integer type.
846 *
847 * @returns pValueResult.
848 * @param pValueResult The input and output value.
849 * @param iBit The bit to set.
850 */
851DECLINLINE(PRTUINT32U) RTUInt32BitClear(PRTUINT32U pValueResult, unsigned iBit)
852{
853#ifdef RTUINT32_HAVE_32BIT_BASICS
854 if (iBit < 32)
855 pValueResult->u &= ~RT_BIT_32(iBit);
856
857#else
858 if (iBit < 16)
859 pValueResult->s.Lo &= ~RT_BIT_32(iBit);
860 else if (iBit < 32)
861 pValueResult->s.Hi &= ~RT_BIT_32(iBit - 32);
862#endif
863 return pValueResult;
864}
865
866
867/**
868 * Tests if a bit in a 32-bit unsigned integer value is set.
869 *
870 * @returns pValueResult.
871 * @param pValueResult The input and output value.
872 * @param iBit The bit to test.
873 */
874DECLINLINE(bool) RTUInt32BitTest(PRTUINT32U pValueResult, unsigned iBit)
875{
876 bool fRc;
877#ifdef RTUINT32_HAVE_32BIT_BASICS
878 if (iBit < 32)
879 fRc = RT_BOOL(pValueResult->u & RT_BIT_32(iBit));
880#else
881 if (iBit < 16)
882 fRc = RT_BOOL(pValueResult->s.Lo & (UINT16_C(1) << iBit));
883 else if (iBit < 32)
884 fRc = RT_BOOL(pValueResult->s.Hi & (UINT16_C(1) << (iBit - 64)));
885#endif
886 else
887 fRc = false;
888 return fRc;
889}
890
891
892/**
893 * Set a range of bits a 32-bit unsigned integer value.
894 *
895 * @returns pValueResult.
896 * @param pValueResult The input and output value.
897 * @param iFirstBit The first bit to test.
898 * @param cBits The number of bits to set.
899 */
900DECLINLINE(PRTUINT32U) RTUInt32BitSetRange(PRTUINT32U pValueResult, unsigned iFirstBit, unsigned cBits)
901{
902 /* bounds check & fix. */
903 if (iFirstBit < 32)
904 {
905#ifdef RTUINT32_HAVE_32BIT_BASICS
906 if (iFirstBit + cBits < 32)
907 pValueResult->u |= (RT_BIT_32(cBits) - 1) << iFirstBit;
908 else
909 pValueResult->u = UINT32_MAX << iFirstBit;
910#else
911 if (iFirstBit + cBits > 32)
912 cBits = 32 - iFirstBit;
913 if (iFirstBit + cBits < 16)
914 pValueResult->s.Lo |= ((UINT16_C(1) << cBits) - 1) << iFirstBit;
915 else if (iFirstBit + cBits < 32 && iFirstBit >= 16)
916 pValueResult->s.Hi |= ((UINT16_C(1) << cBits) - 1) << (iFirstBit - 16);
917 else
918 while (cBits-- > 0)
919 RTUInt32BitSet(pValueResult, iFirstBit++);
920#endif
921 }
922 return pValueResult;
923}
924
925
926/**
927 * Test if all the bits of a 32-bit unsigned integer value are set.
928 *
929 * @returns true if they are, false if they aren't.
930 * @param pValue The input and output value.
931 */
932DECLINLINE(bool) RTUInt32BitAreAllSet(PRTUINT32U pValue)
933{
934 return pValue->s.Hi == UINT16_MAX
935 && pValue->s.Lo == UINT16_MAX;
936}
937
938
939/**
940 * Test if all the bits of a 32-bit unsigned integer value are clear.
941 *
942 * @returns true if they are, false if they aren't.
943 * @param pValue The input and output value.
944 */
945DECLINLINE(bool) RTUInt32BitAreAllClear(PRTUINT32U pValue)
946{
947 return RTUInt32IsZero(pValue);
948}
949
950
951DECLINLINE(unsigned) RTUInt32BitCount(PCRTUINT32U pValue)
952{
953 unsigned cBits;
954 if (pValue->s.Hi != 0)
955 cBits = 16 + ASMBitLastSetU16(pValue->s.Hi);
956 else
957 cBits = ASMBitLastSetU16(pValue->s.Lo);
958 return cBits;
959}
960
961
962/**
963 * Divides a 32-bit unsigned integer value by another, returning both quotient
964 * and remainder.
965 *
966 * @returns pQuotient, NULL if pValue2 is 0.
967 * @param pQuotient Where to return the quotient.
968 * @param pRemainder Where to return the remainder.
969 * @param pValue1 The dividend value.
970 * @param pValue2 The divisor value.
971 */
972DECLINLINE(PRTUINT32U) RTUInt32DivRem(PRTUINT32U pQuotient, PRTUINT32U pRemainder, PCRTUINT32U pValue1, PCRTUINT32U pValue2)
973{
974 int iDiff;
975
976 /*
977 * Sort out all the special cases first.
978 */
979 /* Divide by zero or 1? */
980 if (!pValue2->s.Hi)
981 {
982 if (!pValue2->s.Lo)
983 return NULL;
984
985 if (pValue2->s.Lo == 1)
986 {
987 RTUInt32SetZero(pRemainder);
988 *pQuotient = *pValue1;
989 return pQuotient;
990 }
991 /** @todo RTUInt32DivModByU32 */
992 }
993
994 /* Dividend is smaller? */
995 iDiff = RTUInt32Compare(pValue1, pValue2);
996 if (iDiff < 0)
997 {
998 *pRemainder = *pValue1;
999 RTUInt32SetZero(pQuotient);
1000 }
1001
1002 /* The values are equal? */
1003 else if (iDiff == 0)
1004 {
1005 RTUInt32SetZero(pRemainder);
1006 RTUInt32AssignU8(pQuotient, 1);
1007 }
1008 else
1009 {
1010 /*
1011 * Prepare.
1012 */
1013 unsigned iBitAdder = RTUInt32BitCount(pValue1) - RTUInt32BitCount(pValue2);
1014 RTUINT32U NormDivisor = *pValue2;
1015 if (iBitAdder)
1016 {
1017 RTUInt32ShiftLeft(&NormDivisor, pValue2, iBitAdder);
1018 if (RTUInt32IsLarger(&NormDivisor, pValue1))
1019 {
1020 RTUInt32AssignShiftRight(&NormDivisor, 1);
1021 iBitAdder--;
1022 }
1023 }
1024 else
1025 NormDivisor = *pValue2;
1026
1027 RTUInt32SetZero(pQuotient);
1028 *pRemainder = *pValue1;
1029
1030 /*
1031 * Do the division.
1032 */
1033 if (RTUInt32IsLargerOrEqual(pRemainder, pValue2))
1034 {
1035 for (;;)
1036 {
1037 if (RTUInt32IsLargerOrEqual(pRemainder, &NormDivisor))
1038 {
1039 RTUInt32AssignSub(pRemainder, &NormDivisor);
1040 RTUInt32AssignOrBit(pQuotient, iBitAdder);
1041 }
1042 if (RTUInt32IsSmaller(pRemainder, pValue2))
1043 break;
1044 RTUInt32AssignShiftRight(&NormDivisor, 1);
1045 iBitAdder--;
1046 }
1047 }
1048 }
1049 return pQuotient;
1050}
1051
1052
1053/** @} */
1054
1055RT_C_DECLS_END
1056
1057#endif
1058
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