Changeset 52335 in vbox for trunk/include/iprt
- Timestamp:
- Aug 11, 2014 12:30:20 PM (10 years ago)
- Location:
- trunk/include/iprt
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/asmdefs.mac
r52292 r52335 276 276 ; Begins a C callable exported procedure. 277 277 %macro BEGINPROC_EXPORTED 1 278 %ifdef RT_ASM_WITH_SEH64 279 %ifdef ASM_FORMAT_PE 280 export %1=NAME(%1) 281 %endif 282 global NAME(%1):function 283 proc_frame NAME(%1) 284 %else 278 285 EXPORTEDNAME_EX %1, function 286 %endif 279 287 %endmacro 280 288 -
trunk/include/iprt/bignum.h
r52290 r52335 43 43 typedef uint32_t RTBIGNUMELEMENT; 44 44 #endif 45 /** Pointer to a big integer number element. */ 46 typedef RTBIGNUMELEMENT *PRTBIGNUMELEMENT; 47 /** Pointer to a const big integer number element. */ 48 typedef RTBIGNUMELEMENT const *PCRTBIGNUMELEMENT; 49 45 50 /** The size (in bytes) of one array element. */ 46 51 #if ARCH_BITS == 64 … … 57 62 # define RTBIGNUM_ELEMENT_BIT(iBit) RT_BIT_32(iBit) 58 63 #endif 64 /** The maximum value one element can hold. */ 65 #if ARCH_BITS == 64 66 # define RTBIGNUM_ELEMENT_MAX UINT64_MAX 67 #else 68 # define RTBIGNUM_ELEMENT_MAX UINT32_MAX 69 #endif 70 /** Mask including all the element bits set to 1. */ 71 #define RTBIGNUM_ELEMENT_MASK RTBIGNUM_ELEMENT_MAX 72 59 73 60 74 /** … … 154 168 RTDECL(int) RTBigNumMultiply(PRTBIGNUM pResult, PCRTBIGNUM pMultiplicand, PCRTBIGNUM pMultiplier); 155 169 RTDECL(int) RTBigNumDivide(PRTBIGNUM pQuotient, PRTBIGNUM pRemainder, PCRTBIGNUM pDividend, PCRTBIGNUM pDivisor); 170 RTDECL(int) RTBigNumDivideKnuth(PRTBIGNUM pQuotient, PRTBIGNUM pRemainder, PCRTBIGNUM pDividend, PCRTBIGNUM pDivisor); 171 RTDECL(int) RTBigNumDivideLong(PRTBIGNUM pQuotient, PRTBIGNUM pRemainder, PCRTBIGNUM pDividend, PCRTBIGNUM pDivisor); 156 172 RTDECL(int) RTBigNumModulo(PRTBIGNUM pRemainder, PCRTBIGNUM pDividend, PCRTBIGNUM pDivisor); 157 173 RTDECL(int) RTBigNumExponentiate(PRTBIGNUM pResult, PCRTBIGNUM pBase, PCRTBIGNUM pExponent); 174 RTDECL(int) RTBigNumShiftLeft(PRTBIGNUM pResult, PCRTBIGNUM pValue, uint32_t cBits); 175 RTDECL(int) RTBigNumShiftRight(PRTBIGNUM pResult, PCRTBIGNUM pValue, uint32_t cBits); 158 176 159 177 RTDECL(int) RTBigNumModExp(PRTBIGNUM pResult, PRTBIGNUM pBase, PRTBIGNUM pExponent, PRTBIGNUM pModulus); -
trunk/include/iprt/mangling.h
r52213 r52335 2786 2786 # define RTBigNumDestroy RT_MANGLER(RTBigNumDestroy) 2787 2787 # define RTBigNumDivide RT_MANGLER(RTBigNumDivide) 2788 # define RTBigNumDivideKnuth RT_MANGLER(RTBigNumDivideKnuth) 2789 # define RTBigNumDivideLong RT_MANGLER(RTBigNumDivideLong) 2788 2790 # define RTBigNumExponentiate RT_MANGLER(RTBigNumExponentiate) 2789 2791 # define RTBigNumInit RT_MANGLER(RTBigNumInit) … … 2794 2796 # define RTBigNumNegate RT_MANGLER(RTBigNumNegate) 2795 2797 # define RTBigNumNegateThis RT_MANGLER(RTBigNumNegateThis) 2798 # define RTBigNumShiftLeft RT_MANGLER(RTBigNumShiftLeft) 2799 # define RTBigNumShiftRight RT_MANGLER(RTBigNumShiftRight) 2796 2800 # define RTBigNumSubtract RT_MANGLER(RTBigNumSubtract) 2797 2801 # define RTBigNumToBytesBigEndian RT_MANGLER(RTBigNumToBytesBigEndian) -
trunk/include/iprt/types.h
r51856 r52335 402 402 typedef union RTUINT128U 403 403 { 404 /** Natural view. 405 * WARNING! This member depends on the compiler supporting 128-bit stuff. */ 406 uint128_t u; 407 /** Hi/Low view. */ 404 /** Hi/Low view. 405 * @remarks We put this first so we can have portable initializers 406 * (RTUINT128_INIT) */ 408 407 struct 409 408 { … … 416 415 #endif 417 416 } s; 417 418 /** Natural view. 419 * WARNING! This member depends on the compiler supporting 128-bit stuff. */ 420 uint128_t u; 421 418 422 /** Quad-Word view. */ 419 423 struct … … 480 484 /** Pointer to a const 64-bit unsigned integer union. */ 481 485 typedef const RTUINT128U *PCRTUINT128U; 486 487 /** @def RTUINT128_INIT 488 * Portable RTUINT128U initializer. */ 489 #ifdef RT_BIG_ENDIAN 490 # define RTUINT128_INIT(a_Hi, a_Lo) { a_Hi, a_Lo } 491 #else 492 # define RTUINT128_INIT(a_Hi, a_Lo) { a_Lo, a_Hi } 493 #endif 494 495 /** @def RTUINT128_INIT_C 496 * Portable RTUINT128U initializer for 64-bit constants. */ 497 #ifdef RT_BIG_ENDIAN 498 # define RTUINT128_INIT_C(a_Hi, a_Lo) { UINT64_C(a_Hi), UINT64_C(a_Lo) } 499 #else 500 # define RTUINT128_INIT_C(a_Hi, a_Lo) { UINT64_C(a_Lo), UINT64_C(a_Hi) } 501 #endif 482 502 483 503 -
trunk/include/iprt/uint128.h
r35492 r52335 30 30 #include <iprt/types.h> 31 31 #include <iprt/err.h> 32 #include <iprt/asm.h> 33 #ifdef RT_ARCH_AMD64 34 # include <iprt/asm-math.h> 35 #endif 32 36 33 37 RT_C_DECLS_BEGIN … … 101 105 102 106 103 RTDECL(PRTUINT128U) RTUInt128Add(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 104 RTDECL(PRTUINT128U) RTUInt128Sub(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 105 RTDECL(PRTUINT128U) RTUInt128Div(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 106 RTDECL(PRTUINT128U) RTUInt128Mod(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 107 RTDECL(PRTUINT128U) RTUInt128And(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 108 RTDECL(PRTUINT128U) RTUInt128Or( PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 109 RTDECL(PRTUINT128U) RTUInt128Xor(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 110 RTDECL(PRTUINT128U) RTUInt128ShiftLeft( PRTUINT128U pResult, PCRTUINT128U pValue, int cBits); 111 RTDECL(PRTUINT128U) RTUInt128ShiftRight(PRTUINT128U pResult, PCRTUINT128U pValue, int cBits); 112 RTDECL(PRTUINT128U) RTUInt128BooleanNot(PRTUINT128U pResult, PCRTUINT128U pValue); 113 RTDECL(PRTUINT128U) RTUInt128BitwiseNot(PRTUINT128U pResult, PCRTUINT128U pValue); 107 108 109 /** 110 * Adds two 128-bit unsigned integer values. 111 * 112 * @returns pResult 113 * @param pResult The result variable. 114 * @param pValue1 The first value. 115 * @param pValue2 The second value. 116 */ 117 DECLINLINE(PRTUINT128U) RTUInt128Add(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 118 { 119 pResult->s.Hi = pValue1->s.Hi + pValue2->s.Hi; 120 pResult->s.Lo = pValue1->s.Lo + pValue2->s.Lo; 121 if (pResult->s.Lo < pValue1->s.Lo) 122 pResult->s.Hi++; 123 return pResult; 124 } 125 126 127 /** 128 * Adds a 128-bit and a 64-bit unsigned integer values. 129 * 130 * @returns pResult 131 * @param pResult The result variable. 132 * @param pValue1 The first value. 133 * @param uValue2 The second value, 64-bit. 134 */ 135 DECLINLINE(PRTUINT128U) RTUInt128AddU64(PRTUINT128U pResult, PCRTUINT128U pValue1, uint64_t uValue2) 136 { 137 pResult->s.Hi = pValue1->s.Hi; 138 pResult->s.Lo = pValue1->s.Lo + uValue2; 139 if (pResult->s.Lo < pValue1->s.Lo) 140 pResult->s.Hi++; 141 return pResult; 142 } 143 144 145 /** 146 * Subtracts a 128-bit unsigned integer value from another. 147 * 148 * @returns pResult 149 * @param pResult The result variable. 150 * @param pValue1 The minuend value. 151 * @param pValue2 The subtrahend value. 152 */ 153 DECLINLINE(PRTUINT128U) RTUInt128Sub(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 154 { 155 pResult->s.Lo = pValue1->s.Lo - pValue2->s.Lo; 156 pResult->s.Hi = pValue1->s.Hi - pValue2->s.Hi; 157 if (pResult->s.Lo > pValue1->s.Lo) 158 pResult->s.Hi--; 159 return pResult; 160 } 161 162 163 /** 164 * Multiplies two 128-bit unsigned integer values. 165 * 166 * @returns pResult 167 * @param pResult The result variable. 168 * @param pValue1 The first value. 169 * @param pValue2 The second value. 170 */ 171 DECLINLINE(PRTUINT128U) RTUInt128Mul(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 172 { 173 RTUINT64U uTmp; 174 175 /* multiply all dwords in v1 by v2.dw0. */ 176 pResult->s.Lo = (uint64_t)pValue1->DWords.dw0 * pValue2->DWords.dw0; 177 178 uTmp.u = (uint64_t)pValue1->DWords.dw1 * pValue2->DWords.dw0; 179 pResult->DWords.dw3 = 0; 180 pResult->DWords.dw2 = uTmp.DWords.dw1; 181 pResult->DWords.dw1 += uTmp.DWords.dw0; 182 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 183 if (pResult->DWords.dw2++ == UINT32_MAX) 184 pResult->DWords.dw3++; 185 186 pResult->s.Hi += (uint64_t)pValue1->DWords.dw2 * pValue2->DWords.dw0; 187 pResult->DWords.dw3 += pValue1->DWords.dw3 * pValue2->DWords.dw0; 188 189 /* multiply dw0, dw1 & dw2 in v1 by v2.dw1. */ 190 uTmp.u = (uint64_t)pValue1->DWords.dw0 * pValue2->DWords.dw1; 191 pResult->DWords.dw1 += uTmp.DWords.dw0; 192 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 193 if (pResult->DWords.dw2++ == UINT32_MAX) 194 pResult->DWords.dw3++; 195 196 pResult->DWords.dw2 += uTmp.DWords.dw1; 197 if (pResult->DWords.dw2 < uTmp.DWords.dw1) 198 pResult->DWords.dw3++; 199 200 pResult->s.Hi += (uint64_t)pValue1->DWords.dw1 * pValue2->DWords.dw1; 201 pResult->DWords.dw3 += pValue1->DWords.dw2 * pValue2->DWords.dw1; 202 203 /* multiply dw0 & dw1 in v1 by v2.dw2. */ 204 pResult->s.Hi += (uint64_t)pValue1->DWords.dw0 * pValue2->DWords.dw2; 205 pResult->DWords.dw3 += pValue1->DWords.dw1 * pValue2->DWords.dw2; 206 207 /* multiply dw0 in v1 by v2.dw3. */ 208 pResult->DWords.dw3 += pValue1->DWords.dw0 * pValue2->DWords.dw3; 209 210 return pResult; 211 } 212 213 214 /** 215 * Multiplies an 128-bit unsigned integer by a 64-bit unsigned integer value. 216 * 217 * @returns pResult 218 * @param pResult The result variable. 219 * @param pValue1 The first value. 220 * @param uValue2 The second value, 64-bit. 221 */ 222 #if defined(RT_ARCH_AMD64) 223 RTDECL(PRTUINT128U) RTUInt128MulByU64(PRTUINT128U pResult, PCRTUINT128U pValue1, uint64_t uValue2); 224 #else 225 DECLINLINE(PRTUINT128U) RTUInt128MulByU64(PRTUINT128U pResult, PCRTUINT128U pValue1, uint64_t uValue2) 226 { 227 uint32_t const uLoValue2 = (uint32_t)uValue2; 228 uint32_t const uHiValue2 = (uint32_t)(uValue2 >> 32); 229 RTUINT64U uTmp; 230 231 /* multiply all dwords in v1 by uLoValue1. */ 232 pResult->s.Lo = (uint64_t)pValue1->DWords.dw0 * uLoValue2; 233 234 uTmp.u = (uint64_t)pValue1->DWords.dw1 * uLoValue2; 235 pResult->DWords.dw3 = 0; 236 pResult->DWords.dw2 = uTmp.DWords.dw1; 237 pResult->DWords.dw1 += uTmp.DWords.dw0; 238 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 239 if (pResult->DWords.dw2++ == UINT32_MAX) 240 pResult->DWords.dw3++; 241 242 pResult->s.Hi += (uint64_t)pValue1->DWords.dw2 * uLoValue2; 243 pResult->DWords.dw3 += pValue1->DWords.dw3 * uLoValue2; 244 245 /* multiply dw0, dw1 & dw2 in v1 by uHiValue2. */ 246 uTmp.u = (uint64_t)pValue1->DWords.dw0 * uHiValue2; 247 pResult->DWords.dw1 += uTmp.DWords.dw0; 248 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 249 if (pResult->DWords.dw2++ == UINT32_MAX) 250 pResult->DWords.dw3++; 251 252 pResult->DWords.dw2 += uTmp.DWords.dw1; 253 if (pResult->DWords.dw2 < uTmp.DWords.dw1) 254 pResult->DWords.dw3++; 255 256 pResult->s.Hi += (uint64_t)pValue1->DWords.dw1 * uHiValue2; 257 pResult->DWords.dw3 += pValue1->DWords.dw2 * uHiValue2; 258 259 return pResult; 260 } 261 #endif 262 263 264 /** 265 * Multiplies two 64-bit unsigned integer values with 128-bit precision. 266 * 267 * @returns pResult 268 * @param pResult The result variable. 269 * @param uValue1 The first value. 64-bit. 270 * @param uValue2 The second value, 64-bit. 271 */ 272 DECLINLINE(PRTUINT128U) RTUInt128MulU64ByU64(PRTUINT128U pResult, uint64_t uValue1, uint64_t uValue2) 273 { 274 #ifdef RT_ARCH_AMD64 275 pResult->s.Lo = ASMMult2xU64Ret2xU64(uValue1, uValue2, &pResult->s.Hi); 276 #else 277 uint32_t const uLoValue1 = (uint32_t)uValue1; 278 uint32_t const uHiValue1 = (uint32_t)(uValue1 >> 32); 279 uint32_t const uLoValue2 = (uint32_t)uValue2; 280 uint32_t const uHiValue2 = (uint32_t)(uValue2 >> 32); 281 RTUINT64U uTmp; 282 283 /* Multiply uLoValue1 and uHiValue1 by uLoValue1. */ 284 pResult->s.Lo = (uint64_t)uLoValue1 * uLoValue2; 285 286 uTmp.u = (uint64_t)uHiValue1 * uLoValue2; 287 pResult->DWords.dw3 = 0; 288 pResult->DWords.dw2 = uTmp.DWords.dw1; 289 pResult->DWords.dw1 += uTmp.DWords.dw0; 290 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 291 if (pResult->DWords.dw2++ == UINT32_MAX) 292 pResult->DWords.dw3++; 293 294 /* Multiply uLoValue1 and uHiValue1 by uHiValue2. */ 295 uTmp.u = (uint64_t)uLoValue1 * uHiValue2; 296 pResult->DWords.dw1 += uTmp.DWords.dw0; 297 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 298 if (pResult->DWords.dw2++ == UINT32_MAX) 299 pResult->DWords.dw3++; 300 301 pResult->DWords.dw2 += uTmp.DWords.dw1; 302 if (pResult->DWords.dw2 < uTmp.DWords.dw1) 303 pResult->DWords.dw3++; 304 305 pResult->s.Hi += (uint64_t)uHiValue1 * uHiValue2; 306 #endif 307 return pResult; 308 } 309 310 311 DECLINLINE(PRTUINT128U) RTUInt128DivRem(PRTUINT128U pQuotient, PRTUINT128U pRemainder, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 312 313 /** 314 * Divides a 128-bit unsigned integer value by another. 315 * 316 * @returns pResult 317 * @param pResult The result variable. 318 * @param pValue1 The dividend value. 319 * @param pValue2 The divisor value. 320 */ 321 DECLINLINE(PRTUINT128U) RTUInt128Div(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 322 { 323 RTUINT128U Ignored; 324 return RTUInt128DivRem(pResult, &Ignored, pValue1, pValue2); 325 } 326 327 328 /** 329 * Divides a 128-bit unsigned integer value by another, returning the remainder. 330 * 331 * @returns pResult 332 * @param pResult The result variable (remainder). 333 * @param pValue1 The dividend value. 334 * @param pValue2 The divisor value. 335 */ 336 DECLINLINE(PRTUINT128U) RTUInt128Mod(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 337 { 338 RTUINT128U Ignored; 339 RTUInt128DivRem(&Ignored, pResult, pValue1, pValue2); 340 return pResult; 341 } 342 343 344 /** 345 * Bitwise AND of two 128-bit unsigned integer values. 346 * 347 * @returns pResult 348 * @param pResult The result variable. 349 * @param pValue1 The first value. 350 * @param pValue2 The second value. 351 */ 352 DECLINLINE(PRTUINT128U) RTUInt128And(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 353 { 354 pResult->s.Hi = pValue1->s.Hi & pValue2->s.Hi; 355 pResult->s.Lo = pValue1->s.Lo & pValue2->s.Lo; 356 return pResult; 357 } 358 359 360 /** 361 * Bitwise OR of two 128-bit unsigned integer values. 362 * 363 * @returns pResult 364 * @param pResult The result variable. 365 * @param pValue1 The first value. 366 * @param pValue2 The second value. 367 */ 368 DECLINLINE(PRTUINT128U) RTUInt128Or( PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 369 { 370 pResult->s.Hi = pValue1->s.Hi | pValue2->s.Hi; 371 pResult->s.Lo = pValue1->s.Lo | pValue2->s.Lo; 372 return pResult; 373 } 374 375 376 /** 377 * Bitwise XOR of two 128-bit unsigned integer values. 378 * 379 * @returns pResult 380 * @param pResult The result variable. 381 * @param pValue1 The first value. 382 * @param pValue2 The second value. 383 */ 384 DECLINLINE(PRTUINT128U) RTUInt128Xor(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 385 { 386 pResult->s.Hi = pValue1->s.Hi ^ pValue2->s.Hi; 387 pResult->s.Lo = pValue1->s.Lo ^ pValue2->s.Lo; 388 return pResult; 389 } 390 391 392 /** 393 * Shifts a 128-bit unsigned integer value @a cBits to the left. 394 * 395 * @returns pResult 396 * @param pResult The result variable. 397 * @param pValue The value to shift. 398 * @param cBits The number of bits to shift it. 399 */ 400 DECLINLINE(PRTUINT128U) RTUInt128ShiftLeft(PRTUINT128U pResult, PCRTUINT128U pValue, int cBits) 401 { 402 cBits &= 127; 403 if (cBits < 64) 404 { 405 pResult->s.Lo = pValue->s.Lo << cBits; 406 pResult->s.Hi = (pValue->s.Hi << cBits) | (pValue->s.Lo >> (64 - cBits)); 407 } 408 else 409 { 410 pResult->s.Lo = 0; 411 pResult->s.Hi = pValue->s.Lo << (cBits - 64); 412 } 413 return pResult; 414 } 415 416 417 /** 418 * Shifts a 128-bit unsigned integer value @a cBits to the right. 419 * 420 * @returns pResult 421 * @param pResult The result variable. 422 * @param pValue The value to shift. 423 * @param cBits The number of bits to shift it. 424 */ 425 DECLINLINE(PRTUINT128U) RTUInt128ShiftRight(PRTUINT128U pResult, PCRTUINT128U pValue, int cBits) 426 { 427 cBits &= 127; 428 if (cBits < 64) 429 { 430 pResult->s.Hi = pValue->s.Hi >> cBits; 431 pResult->s.Lo = (pValue->s.Lo >> cBits) | (pValue->s.Hi << (64 - cBits)); 432 } 433 else 434 { 435 pResult->s.Hi = 0; 436 pResult->s.Lo = pValue->s.Hi >> (cBits - 64); 437 } 438 return pResult; 439 } 440 441 442 /** 443 * Boolean not (result 0 or 1). 444 * 445 * @returns pResult. 446 * @param pResult The result variable. 447 * @param pValue The value. 448 */ 449 DECLINLINE(PRTUINT128U) RTUInt128BooleanNot(PRTUINT128U pResult, PCRTUINT128U pValue) 450 { 451 pResult->s.Hi = 0; 452 pResult->s.Lo = pValue->s.Lo || pValue->s.Hi ? 0 : 1; 453 return pResult; 454 } 455 456 457 /** 458 * Bitwise not (flips each bit of the 128 bits). 459 * 460 * @returns pResult. 461 * @param pResult The result variable. 462 * @param pValue The value. 463 */ 464 DECLINLINE(PRTUINT128U) RTUInt128BitwiseNot(PRTUINT128U pResult, PCRTUINT128U pValue) 465 { 466 pResult->s.Hi = ~pValue->s.Hi; 467 pResult->s.Lo = ~pValue->s.Lo; 468 return pResult; 469 } 114 470 115 471 … … 239 595 240 596 241 RTDECL(PRTUINT128U) RTUInt128AssignAdd(PRTUINT128U pValue1Result, PCRTUINT128U pValue2); 242 RTDECL(PRTUINT128U) RTUInt128AssignSub(PRTUINT128U pValue1Result, PCRTUINT128U pValue2); 243 RTDECL(PRTUINT128U) RTUInt128AssignDiv(PRTUINT128U pValue1Result, PCRTUINT128U pValue2); 244 RTDECL(PRTUINT128U) RTUInt128AssignMod(PRTUINT128U pValue1Result, PCRTUINT128U pValue2); 597 /** 598 * Adds two 128-bit unsigned integer values, storing the result in the first. 599 * 600 * @returns pValue1Result. 601 * @param pValue1Result The first value and result. 602 * @param pValue2 The second value. 603 */ 604 DECLINLINE(PRTUINT128U) RTUInt128AssignAdd(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 605 { 606 uint64_t const uTmp = pValue1Result->s.Lo; 607 pValue1Result->s.Lo += pValue2->s.Lo; 608 if (pValue1Result->s.Lo < uTmp) 609 pValue1Result->s.Hi++; 610 pValue1Result->s.Hi += pValue2->s.Hi; 611 return pValue1Result; 612 } 613 614 615 /** 616 * Adds a 64-bit unsigned integer value to a 128-bit unsigned integer values, 617 * storing the result in the 128-bit one. 618 * 619 * @returns pValue1Result. 620 * @param pValue1Result The first value and result. 621 * @param uValue2 The second value, 64-bit. 622 */ 623 DECLINLINE(PRTUINT128U) RTUInt128AssignAddU64(PRTUINT128U pValue1Result, uint64_t uValue2) 624 { 625 pValue1Result->s.Lo += uValue2; 626 if (pValue1Result->s.Lo < uValue2) 627 pValue1Result->s.Hi++; 628 return pValue1Result; 629 } 630 631 632 /** 633 * Subtracts two 128-bit unsigned integer values, storing the result in the 634 * first. 635 * 636 * @returns pValue1Result. 637 * @param pValue1Result The minuend value and result. 638 * @param pValue2 The subtrahend value. 639 */ 640 DECLINLINE(PRTUINT128U) RTUInt128AssignSub(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 641 { 642 uint64_t const uTmp = pValue1Result->s.Lo; 643 pValue1Result->s.Lo -= pValue2->s.Lo; 644 if (pValue1Result->s.Lo > uTmp) 645 pValue1Result->s.Hi--; 646 pValue1Result->s.Hi -= pValue2->s.Hi; 647 return pValue1Result; 648 } 649 650 651 /** 652 * Multiplies two 128-bit unsigned integer values, storing the result in the 653 * first. 654 * 655 * @returns pValue1Result. 656 * @param pValue1Result The first value and result. 657 * @param pValue2 The second value. 658 */ 659 DECLINLINE(PRTUINT128U) RTUInt128AssignMul(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 660 { 661 RTUINT128U Result; 662 RTUInt128Mul(&Result, pValue1Result, pValue2); 663 *pValue1Result = Result; 664 return pValue1Result; 665 } 666 667 668 /** 669 * Divides a 128-bit unsigned integer value by another, storing the result in 670 * the first. 671 * 672 * @returns pValue1Result. 673 * @param pValue1Result The dividend value and result. 674 * @param pValue2 The divisor value. 675 */ 676 DECLINLINE(PRTUINT128U) RTUInt128AssignDiv(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 677 { 678 RTUINT128U Result; 679 RTUINT128U Ignored; 680 RTUInt128DivRem(&Result, &Ignored, pValue1Result, pValue2); 681 *pValue1Result = Result; 682 return pValue1Result; 683 } 684 685 686 /** 687 * Divides a 128-bit unsigned integer value by another, storing the remainder in 688 * the first. 689 * 690 * @returns pValue1Result. 691 * @param pValue1Result The dividend value and result (remainder). 692 * @param pValue2 The divisor value. 693 */ 694 DECLINLINE(PRTUINT128U) RTUInt128AssignMod(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 695 { 696 RTUINT128U Ignored; 697 RTUINT128U Result; 698 RTUInt128DivRem(&Ignored, &Result, pValue1Result, pValue2); 699 *pValue1Result = Result; 700 return pValue1Result; 701 } 245 702 246 703 … … 313 770 return pValue1Result; 314 771 } 772 773 774 /** 775 * ORs in a bit and assign the result to the input value. 776 * 777 * @returns pValue1Result. 778 * @param pValue1Result The first value and result. 779 * @param iBit The bit to set (0 based). 780 */ 781 DECLINLINE(PRTUINT128U) RTUInt128AssignOrBit(PRTUINT128U pValue1Result, uint32_t iBit) 782 { 783 #if ARCH_BITS >= 64 784 if (iBit >= 64) 785 pValue1Result->s.Hi |= RT_BIT_64(iBit - 64); 786 else 787 pValue1Result->s.Lo |= RT_BIT_64(iBit); 788 #else 789 if (iBit >= 64) 790 { 791 if (iBit >= 96) 792 pValue1Result->DWords.dw3 |= RT_BIT_32(iBit - 96); 793 else 794 pValue1Result->DWords.dw2 |= RT_BIT_32(iBit - 64); 795 } 796 else 797 { 798 if (iBit >= 32) 799 pValue1Result->DWords.dw1 |= RT_BIT_32(iBit - 32); 800 else 801 pValue1Result->DWords.dw0 |= RT_BIT_32(iBit); 802 } 803 #endif 804 return pValue1Result; 805 } 806 315 807 316 808 … … 457 949 return 0; 458 950 #else 951 if (pValue1->DWords.dw3 != pValue2->DWords.dw3) 952 return pValue1->DWords.dw3 > pValue2->DWords.dw3 ? 1 : -1; 953 if (pValue1->DWords.dw2 != pValue2->DWords.dw2) 954 return pValue1->DWords.dw2 > pValue2->DWords.dw2 ? 1 : -1; 955 if (pValue1->DWords.dw1 != pValue2->DWords.dw1) 956 return pValue1->DWords.dw1 > pValue2->DWords.dw1 ? 1 : -1; 459 957 if (pValue1->DWords.dw0 != pValue2->DWords.dw0) 460 958 return pValue1->DWords.dw0 > pValue2->DWords.dw0 ? 1 : -1; 461 if (pValue1->DWords.dw1 != pValue2->DWords.dw1)462 return pValue1->DWords.dw1 > pValue2->DWords.dw1 ? 1 : -1;463 if (pValue1->DWords.dw2 != pValue2->DWords.dw2)464 return pValue1->DWords.dw2 > pValue2->DWords.dw2 ? 1 : -1;465 if (pValue1->DWords.dw3 != pValue2->DWords.dw3)466 return pValue1->DWords.dw3 > pValue2->DWords.dw3 ? 1 : -1;467 959 return 0; 960 #endif 961 } 962 963 964 /** 965 * Tests if a 128-bit unsigned integer value is smaller than another. 966 * 967 * @returns true if the first value is smaller, false if not. 968 * @param pValue1 The first value. 969 * @param pValue2 The second value. 970 */ 971 DECLINLINE(bool) RTUInt128IsSmaller(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 972 { 973 #if ARCH_BITS >= 64 974 return pValue1->s.Hi < pValue2->s.Hi 975 || ( pValue1->s.Hi == pValue2->s.Hi 976 && pValue1->s.Lo < pValue2->s.Lo); 977 #else 978 return pValue1->DWords.dw3 < pValue2->DWords.dw3 979 || ( pValue1->DWords.dw3 == pValue2->DWords.dw3 980 && ( pValue1->DWords.dw2 < pValue2->DWords.dw2 981 || ( pValue1->DWords.dw2 == pValue2->DWords.dw2 982 && ( pValue1->DWords.dw1 < pValue2->DWords.dw1 983 || ( pValue1->DWords.dw1 == pValue2->DWords.dw1 984 && pValue1->DWords.dw0 < pValue2->DWords.dw0))))); 985 #endif 986 } 987 988 989 /** 990 * Tests if a 128-bit unsigned integer value is larger than another. 991 * 992 * @returns true if the first value is larger, false if not. 993 * @param pValue1 The first value. 994 * @param pValue2 The second value. 995 */ 996 DECLINLINE(bool) RTUInt128IsLarger(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 997 { 998 #if ARCH_BITS >= 64 999 return pValue1->s.Hi > pValue2->s.Hi 1000 || ( pValue1->s.Hi == pValue2->s.Hi 1001 && pValue1->s.Lo > pValue2->s.Lo); 1002 #else 1003 return pValue1->DWords.dw3 > pValue2->DWords.dw3 1004 || ( pValue1->DWords.dw3 == pValue2->DWords.dw3 1005 && ( pValue1->DWords.dw2 > pValue2->DWords.dw2 1006 || ( pValue1->DWords.dw2 == pValue2->DWords.dw2 1007 && ( pValue1->DWords.dw1 > pValue2->DWords.dw1 1008 || ( pValue1->DWords.dw1 == pValue2->DWords.dw1 1009 && pValue1->DWords.dw0 > pValue2->DWords.dw0))))); 1010 #endif 1011 } 1012 1013 1014 /** 1015 * Tests if a 128-bit unsigned integer value is larger or equal than another. 1016 * 1017 * @returns true if the first value is larger or equal, false if not. 1018 * @param pValue1 The first value. 1019 * @param pValue2 The second value. 1020 */ 1021 DECLINLINE(bool) RTUInt128IsLargerOrEqual(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 1022 { 1023 #if ARCH_BITS >= 64 1024 return pValue1->s.Hi > pValue2->s.Hi 1025 || ( pValue1->s.Hi == pValue2->s.Hi 1026 && pValue1->s.Lo >= pValue2->s.Lo); 1027 #else 1028 return pValue1->DWords.dw3 > pValue2->DWords.dw3 1029 || ( pValue1->DWords.dw3 == pValue2->DWords.dw3 1030 && ( pValue1->DWords.dw2 > pValue2->DWords.dw2 1031 || ( pValue1->DWords.dw2 == pValue2->DWords.dw2 1032 && ( pValue1->DWords.dw1 > pValue2->DWords.dw1 1033 || ( pValue1->DWords.dw1 == pValue2->DWords.dw1 1034 && pValue1->DWords.dw0 >= pValue2->DWords.dw0))))); 468 1035 #endif 469 1036 } … … 691 1258 } 692 1259 1260 1261 DECLINLINE(uint32_t) RTUInt128BitCount(PCRTUINT128U pValue) 1262 { 1263 uint32_t cBits; 1264 if (pValue->s.Hi != 0) 1265 { 1266 if (pValue->DWords.dw3) 1267 cBits = 96 + ASMBitLastSetU32(pValue->DWords.dw3); 1268 else 1269 cBits = 64 + ASMBitLastSetU32(pValue->DWords.dw2); 1270 } 1271 else 1272 { 1273 if (pValue->DWords.dw1) 1274 cBits = 32 + ASMBitLastSetU32(pValue->DWords.dw1); 1275 else 1276 cBits = 0 + ASMBitLastSetU32(pValue->DWords.dw0); 1277 } 1278 return cBits; 1279 } 1280 1281 1282 /** 1283 * Divides a 128-bit unsigned integer value by another, returning both quotient 1284 * and remainder. 1285 * 1286 * @returns pQuotient, NULL if pValue2 is 0. 1287 * @param pQuotient Where to return the quotient. 1288 * @param pRemainder Where to return the remainder. 1289 * @param pValue1 The dividend value. 1290 * @param pValue2 The divisor value. 1291 */ 1292 DECLINLINE(PRTUINT128U) RTUInt128DivRem(PRTUINT128U pQuotient, PRTUINT128U pRemainder, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 1293 { 1294 int iDiff; 1295 1296 /* 1297 * Sort out all the special cases first. 1298 */ 1299 /* Divide by zero or 1? */ 1300 if (!pValue2->s.Hi) 1301 { 1302 if (!pValue2->s.Lo) 1303 return NULL; 1304 1305 if (pValue2->s.Lo == 1) 1306 { 1307 RTUInt128SetZero(pRemainder); 1308 *pQuotient = *pValue1; 1309 return pQuotient; 1310 } 1311 /** @todo RTUint128DivModBy64 */ 1312 } 1313 1314 /* Dividend is smaller? */ 1315 iDiff = RTUInt128Compare(pValue1, pValue2); 1316 if (iDiff < 0) 1317 { 1318 *pRemainder = *pValue1; 1319 RTUInt128SetZero(pQuotient); 1320 } 1321 1322 /* The values are equal? */ 1323 else if (iDiff == 0) 1324 { 1325 RTUInt128SetZero(pRemainder); 1326 RTUInt128AssignU64(pQuotient, 1); 1327 } 1328 else 1329 { 1330 /* 1331 * Prepare. 1332 */ 1333 uint32_t iBitAdder = RTUInt128BitCount(pValue1) - RTUInt128BitCount(pValue2); 1334 RTUINT128U NormDivisor = *pValue2; 1335 if (iBitAdder) 1336 { 1337 RTUInt128ShiftLeft(&NormDivisor, pValue2, iBitAdder); 1338 if (RTUInt128IsLarger(&NormDivisor, pValue1)) 1339 { 1340 RTUInt128AssignShiftRight(&NormDivisor, 1); 1341 iBitAdder--; 1342 } 1343 } 1344 else 1345 NormDivisor = *pValue2; 1346 1347 RTUInt128SetZero(pQuotient); 1348 *pRemainder = *pValue1; 1349 1350 /* 1351 * Do the division. 1352 */ 1353 if (RTUInt128IsLargerOrEqual(pRemainder, pValue2)) 1354 { 1355 for (;;) 1356 { 1357 if (RTUInt128IsLargerOrEqual(pRemainder, &NormDivisor)) 1358 { 1359 RTUInt128AssignSub(pRemainder, &NormDivisor); 1360 RTUInt128AssignOrBit(pQuotient, iBitAdder); 1361 } 1362 if (RTUInt128IsSmaller(pRemainder, pValue2)) 1363 break; 1364 RTUInt128AssignShiftRight(&NormDivisor, 1); 1365 iBitAdder--; 1366 } 1367 } 1368 } 1369 return pQuotient; 1370 } 1371 1372 693 1373 /** @} */ 694 1374
Note:
See TracChangeset
for help on using the changeset viewer.