[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 |
|
---|
| 36 | RT_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] | 50 | DECLINLINE(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] | 70 | DECLINLINE(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] | 91 | DECLINLINE(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] | 116 | DECLINLINE(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] | 134 | DECLINLINE(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] | 152 | DECLINLINE(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] | 170 | DECLINLINE(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] | 221 | DECLINLINE(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] | 267 | DECLINLINE(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] | 302 | DECLINLINE(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] | 312 | DECLINLINE(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] | 327 | DECLINLINE(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] | 343 | DECLINLINE(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] | 359 | DECLINLINE(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] | 375 | DECLINLINE(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] | 391 | DECLINLINE(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] | 416 | DECLINLINE(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] | 440 | DECLINLINE(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] | 455 | DECLINLINE(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] | 470 | DECLINLINE(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] | 492 | DECLINLINE(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] | 514 | DECLINLINE(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] | 536 | DECLINLINE(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] | 558 | DECLINLINE(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] | 580 | DECLINLINE(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] | 599 | DECLINLINE(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] | 618 | DECLINLINE(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] | 635 | DECLINLINE(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] | 653 | DECLINLINE(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] | 671 | DECLINLINE(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] | 695 | DECLINLINE(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] | 717 | DECLINLINE(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] | 739 | DECLINLINE(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] | 775 | DECLINLINE(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] | 798 | DECLINLINE(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] | 846 | DECLINLINE(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] | 859 | DECLINLINE(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] | 881 | DECLINLINE(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] | 897 | DECLINLINE(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] | 926 | DECLINLINE(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] | 951 | DECLINLINE(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] | 976 | DECLINLINE(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] | 1001 | DECLINLINE(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] | 1022 | DECLINLINE(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] | 1035 | DECLINLINE(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] | 1070 | DECLINLINE(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] | 1105 | DECLINLINE(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] | 1144 | DECLINLINE(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] | 1182 | DECLINLINE(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] | 1202 | DECLINLINE(bool) RTUInt64BitAreAllClear(PRTUINT64U pValue)
|
---|
[35488] | 1203 | {
|
---|
[60482] | 1204 | return RTUInt64IsZero(pValue);
|
---|
[35488] | 1205 | }
|
---|
| 1206 |
|
---|
[52335] | 1207 |
|
---|
[60482] | 1208 | DECLINLINE(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] | 1247 | DECLINLINE(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 |
|
---|
| 1330 | RT_C_DECLS_END
|
---|
| 1331 |
|
---|
[76585] | 1332 | #endif /* !IPRT_INCLUDED_uint64_h */
|
---|
[35488] | 1333 |
|
---|