Changeset 94511 in vbox
- Timestamp:
- Apr 7, 2022 1:17:57 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 150856
- Location:
- trunk
- Files:
-
- 5 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/mangling.h
r94311 r94511 4055 4055 # define RTUInt128MulByU64 RT_MANGLER(RTUInt128MulByU64) 4056 4056 # define RTUInt128MulByU64_EndProc RT_MANGLER(RTUInt128MulByU64_EndProc) 4057 # define RTUInt128MulByU64Ex RT_MANGLER(RTUInt128MulByU64Ex) 4058 # define RTUInt128MulByU64Ex_EndProc RT_MANGLER(RTUInt128MulByU64Ex_EndProc) 4057 4059 # define RTUtf16Copy RT_MANGLER(RTUtf16Copy) 4058 4060 # define RTUtf16CopyAscii RT_MANGLER(RTUtf16CopyAscii) -
trunk/include/iprt/uint128.h
r93115 r94511 51 51 * @param pValue The input and output value. 52 52 */ 53 DECLINLINE(bool) RTUInt128IsZero(P RTUINT128U pValue)53 DECLINLINE(bool) RTUInt128IsZero(PCRTUINT128U pValue) 54 54 { 55 55 #if ARCH_BITS >= 64 … … 307 307 pResult->s.Hi += (uint64_t)uHiValue1 * uHiValue2; 308 308 #endif 309 return pResult; 310 } 311 312 313 /** 314 * Multiplies an 128-bit unsigned integer by a 64-bit unsigned integer value, 315 * returning a 256-bit result (top 64 bits are zero). 316 * 317 * @returns pResult 318 * @param pResult The result variable. 319 * @param pValue1 The first value. 320 * @param uValue2 The second value, 64-bit. 321 */ 322 #if defined(RT_ARCH_AMD64) 323 RTDECL(PRTUINT256U) RTUInt128MulByU64Ex(PRTUINT256U pResult, PCRTUINT128U pValue1, uint64_t uValue2); 324 #else 325 DECLINLINE(PRTUINT256U) RTUInt128MulByU64Ex(PRTUINT256U pResult, PCRTUINT128U pValue1, uint64_t uValue2) 326 { 327 /* multiply the two qwords in pValue1 by uValue2. */ 328 uint64_t uTmp = 0; 329 pResult->QWords.qw0 = ASMMult2xU64Ret2xU64(pValue1->s.Lo, uValue2, &uTmp); 330 pResult->QWords.qw1 = ASMMult2xU64Ret2xU64(pValue1->s.Hi, uValue2, &pResult->QWords.qw2); 331 pResult->QWords.qw3 = 0; 332 pResult->QWords.qw1 += uTmp; 333 if (pResult->QWords.qw1 < uTmp) 334 pResult->QWords.qw2++; /* This cannot overflow AFAIK: 0xffff*0xffff = 0xFFFE0001 */ 335 336 return pResult; 337 } 338 #endif 339 340 341 /** 342 * Multiplies two 128-bit unsigned integer values, returning a 256-bit result. 343 * 344 * @returns pResult 345 * @param pResult The result variable. 346 * @param pValue1 The first value. 347 * @param pValue2 The second value. 348 */ 349 DECLINLINE(PRTUINT256U) RTUInt128MulEx(PRTUINT256U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 350 { 351 RTUInt128MulByU64Ex(pResult, pValue1, pValue2->s.Lo); 352 if (pValue2->s.Hi) 353 { 354 /* Multiply the two qwords in pValue1 by the high part of uValue2. */ 355 uint64_t uTmpHi = 0; 356 uint64_t uTmpLo = ASMMult2xU64Ret2xU64(pValue1->s.Lo, pValue2->s.Hi, &uTmpHi); 357 pResult->QWords.qw1 += uTmpLo; 358 if (pResult->QWords.qw1 < uTmpLo) 359 if (++pResult->QWords.qw2 == 0) 360 pResult->QWords.qw3++; /* (cannot overflow, was == 0) */ 361 pResult->QWords.qw2 += uTmpHi; 362 if (pResult->QWords.qw2 < uTmpHi) 363 pResult->QWords.qw3++; /* (cannot overflow, was <= 1) */ 364 365 uTmpLo = ASMMult2xU64Ret2xU64(pValue1->s.Hi, pValue2->s.Hi, &uTmpHi); 366 pResult->QWords.qw2 += uTmpLo; 367 if (pResult->QWords.qw2 < uTmpLo) 368 pResult->QWords.qw3++; /* (cannot overflow, was <= 2) */ 369 pResult->QWords.qw3 += uTmpHi; 370 } 371 309 372 return pResult; 310 373 } … … 1281 1344 1282 1345 1346 /** 1347 * Number of significant bits in the value. 1348 * 1349 * This is the same a ASMBitLastSetU64 and ASMBitLastSetU32. 1350 * 1351 * @returns 0 if zero, 1-base index of the last bit set. 1352 * @param pValue The value to examine. 1353 */ 1283 1354 DECLINLINE(uint32_t) RTUInt128BitCount(PCRTUINT128U pValue) 1284 1355 { -
trunk/include/iprt/uint256.h
r94493 r94511 1 1 /** @file 2 * IPRT - RTUINT 128U & uint128_tmethods.2 * IPRT - RTUINT256U methods. 3 3 */ 4 4 … … 24 24 */ 25 25 26 #ifndef IPRT_INCLUDED_uint 128_h27 #define IPRT_INCLUDED_uint 128_h26 #ifndef IPRT_INCLUDED_uint256_h 27 #define IPRT_INCLUDED_uint256_h 28 28 #ifndef RT_WITHOUT_PRAGMA_ONCE 29 29 # pragma once … … 39 39 RT_C_DECLS_BEGIN 40 40 41 /** @defgroup grp_rt_uint 128 RTUInt128 - 128-bit Unsigned Integer Methods41 /** @defgroup grp_rt_uint256 RTUInt256 - 256-bit Unsigned Integer Methods 42 42 * @ingroup grp_rt 43 43 * @{ … … 46 46 47 47 /** 48 * Test if a 128-bit unsigned integer value is zero.48 * Test if a 256-bit unsigned integer value is zero. 49 49 * 50 50 * @returns true if they are, false if they aren't. 51 51 * @param pValue The input and output value. 52 52 */ 53 DECLINLINE(bool) RTUInt 128IsZero(PRTUINT128U pValue)53 DECLINLINE(bool) RTUInt256IsZero(PCRTUINT256U pValue) 54 54 { 55 55 #if ARCH_BITS >= 64 56 return pValue->s.Hi == 0 57 && pValue->s.Lo == 0; 56 return pValue->QWords.qw0 == 0 57 && pValue->QWords.qw1 == 0 58 && pValue->QWords.qw2 == 0 59 && pValue->QWords.qw3 == 0; 58 60 #else 59 61 return pValue->DWords.dw0 == 0 60 62 && pValue->DWords.dw1 == 0 61 63 && pValue->DWords.dw2 == 0 62 && pValue->DWords.dw3 == 0; 64 && pValue->DWords.dw3 == 0 65 && pValue->DWords.dw4 == 0 66 && pValue->DWords.dw5 == 0 67 && pValue->DWords.dw6 == 0 68 && pValue->DWords.dw7 == 0; 63 69 #endif 64 70 } … … 66 72 67 73 /** 68 * Set a 128-bit unsigned integer value to zero.69 * 70 * @returns pResult 71 * @param pResult The result variable. 72 */ 73 DECLINLINE(PRTUINT 128U) RTUInt128SetZero(PRTUINT128U pResult)74 * Set a 256-bit unsigned integer value to zero. 75 * 76 * @returns pResult 77 * @param pResult The result variable. 78 */ 79 DECLINLINE(PRTUINT256U) RTUInt256SetZero(PRTUINT256U pResult) 74 80 { 75 81 #if ARCH_BITS >= 64 76 pResult->s.Hi = 0; 77 pResult->s.Lo = 0; 82 pResult->QWords.qw0 = 0; 83 pResult->QWords.qw1 = 0; 84 pResult->QWords.qw2 = 0; 85 pResult->QWords.qw3 = 0; 78 86 #else 79 87 pResult->DWords.dw0 = 0; … … 81 89 pResult->DWords.dw2 = 0; 82 90 pResult->DWords.dw3 = 0; 91 pResult->DWords.dw4 = 0; 92 pResult->DWords.dw5 = 0; 93 pResult->DWords.dw6 = 0; 94 pResult->DWords.dw7 = 0; 83 95 #endif 84 96 return pResult; … … 87 99 88 100 /** 89 * Set a 128-bit unsigned integer value to the maximum value.90 * 91 * @returns pResult 92 * @param pResult The result variable. 93 */ 94 DECLINLINE(PRTUINT 128U) RTUInt128SetMax(PRTUINT128U pResult)101 * Set a 256-bit unsigned integer value to the maximum value. 102 * 103 * @returns pResult 104 * @param pResult The result variable. 105 */ 106 DECLINLINE(PRTUINT256U) RTUInt256SetMax(PRTUINT256U pResult) 95 107 { 96 108 #if ARCH_BITS >= 64 97 pResult->s.Hi = UINT64_MAX; 98 pResult->s.Lo = UINT64_MAX; 109 pResult->QWords.qw0 = UINT64_MAX; 110 pResult->QWords.qw1 = UINT64_MAX; 111 pResult->QWords.qw2 = UINT64_MAX; 112 pResult->QWords.qw3 = UINT64_MAX; 99 113 #else 100 114 pResult->DWords.dw0 = UINT32_MAX; … … 102 116 pResult->DWords.dw2 = UINT32_MAX; 103 117 pResult->DWords.dw3 = UINT32_MAX; 118 pResult->DWords.dw4 = UINT32_MAX; 119 pResult->DWords.dw5 = UINT32_MAX; 120 pResult->DWords.dw6 = UINT32_MAX; 121 pResult->DWords.dw7 = UINT32_MAX; 104 122 #endif 105 123 return pResult; … … 110 128 111 129 /** 112 * Adds two 128-bit unsigned integer values.130 * Adds two 256-bit unsigned integer values. 113 131 * 114 132 * @returns pResult … … 117 135 * @param pValue2 The second value. 118 136 */ 119 DECLINLINE(PRTUINT128U) RTUInt128Add(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 120 { 121 pResult->s.Hi = pValue1->s.Hi + pValue2->s.Hi; 122 pResult->s.Lo = pValue1->s.Lo + pValue2->s.Lo; 123 if (pResult->s.Lo < pValue1->s.Lo) 124 pResult->s.Hi++; 125 return pResult; 126 } 127 128 129 /** 130 * Adds a 128-bit and a 64-bit unsigned integer values. 137 DECLINLINE(PRTUINT256U) RTUInt256Add(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2) 138 { 139 unsigned uCarry; 140 pResult->QWords.qw0 = pValue1->QWords.qw0 + pValue2->QWords.qw0; 141 uCarry = pResult->QWords.qw0 < pValue1->QWords.qw0; 142 143 pResult->QWords.qw1 = pValue1->QWords.qw1 + pValue2->QWords.qw1 + uCarry; 144 uCarry = uCarry ? pResult->QWords.qw1 <= pValue1->QWords.qw1 : pResult->QWords.qw1 < pValue1->QWords.qw1; 145 146 pResult->QWords.qw2 = pValue1->QWords.qw2 + pValue2->QWords.qw2 + uCarry; 147 uCarry = uCarry ? pResult->QWords.qw2 <= pValue1->QWords.qw2 : pResult->QWords.qw2 < pValue1->QWords.qw2; 148 149 pResult->QWords.qw3 = pValue1->QWords.qw3 + pValue2->QWords.qw3 + uCarry; 150 return pResult; 151 } 152 153 154 /** 155 * Adds a 256-bit and a 64-bit unsigned integer values. 131 156 * 132 157 * @returns pResult … … 135 160 * @param uValue2 The second value, 64-bit. 136 161 */ 137 DECLINLINE(PRTUINT128U) RTUInt128AddU64(PRTUINT128U pResult, PCRTUINT128U pValue1, uint64_t uValue2) 138 { 139 pResult->s.Hi = pValue1->s.Hi; 140 pResult->s.Lo = pValue1->s.Lo + uValue2; 141 if (pResult->s.Lo < pValue1->s.Lo) 142 pResult->s.Hi++; 143 return pResult; 144 } 145 146 147 /** 148 * Subtracts a 128-bit unsigned integer value from another. 162 DECLINLINE(PRTUINT256U) RTUInt256AddU64(PRTUINT256U pResult, PCRTUINT256U pValue1, uint64_t uValue2) 163 { 164 pResult->QWords.qw3 = pValue1->QWords.qw3; 165 pResult->QWords.qw2 = pValue1->QWords.qw2; 166 pResult->QWords.qw1 = pValue1->QWords.qw1; 167 pResult->QWords.qw0 = pValue1->QWords.qw0 + uValue2; 168 if (pResult->QWords.qw0 < uValue2) 169 if (pResult->QWords.qw1++ == UINT64_MAX) 170 if (pResult->QWords.qw2++ == UINT64_MAX) 171 pResult->QWords.qw3++; 172 return pResult; 173 } 174 175 176 /** 177 * Subtracts a 256-bit unsigned integer value from another. 149 178 * 150 179 * @returns pResult … … 153 182 * @param pValue2 The subtrahend value. 154 183 */ 155 DECLINLINE(PRTUINT128U) RTUInt128Sub(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 156 { 157 pResult->s.Lo = pValue1->s.Lo - pValue2->s.Lo; 158 pResult->s.Hi = pValue1->s.Hi - pValue2->s.Hi; 159 if (pResult->s.Lo > pValue1->s.Lo) 160 pResult->s.Hi--; 161 return pResult; 162 } 163 164 165 /** 166 * Multiplies two 128-bit unsigned integer values. 184 DECLINLINE(PRTUINT256U) RTUInt256Sub(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2) 185 { 186 unsigned uBorrow; 187 pResult->QWords.qw0 = pValue1->QWords.qw0 - pValue2->QWords.qw0; 188 uBorrow = pResult->QWords.qw0 > pValue1->QWords.qw0; 189 190 pResult->QWords.qw1 = pValue1->QWords.qw1 - pValue2->QWords.qw1 - uBorrow; 191 uBorrow = uBorrow ? pResult->QWords.qw1 >= pValue1->QWords.qw1 : pResult->QWords.qw1 > pValue1->QWords.qw1; 192 193 pResult->QWords.qw2 = pValue1->QWords.qw2 - pValue2->QWords.qw2 - uBorrow; 194 uBorrow = uBorrow ? pResult->QWords.qw2 >= pValue1->QWords.qw2 : pResult->QWords.qw2 > pValue1->QWords.qw2; 195 196 pResult->QWords.qw3 = pValue1->QWords.qw3 - pValue2->QWords.qw3 - uBorrow; 197 return pResult; 198 } 199 200 201 /** 202 * Multiplies two 256-bit unsigned integer values. 167 203 * 168 204 * @returns pResult … … 171 207 * @param pValue2 The second value. 172 208 */ 173 DECLINLINE(PRTUINT128U) RTUInt128Mul(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 174 { 175 RTUINT64U uTmp; 176 177 /* multiply all dwords in v1 by v2.dw0. */ 178 pResult->s.Lo = (uint64_t)pValue1->DWords.dw0 * pValue2->DWords.dw0; 179 180 uTmp.u = (uint64_t)pValue1->DWords.dw1 * pValue2->DWords.dw0; 181 pResult->DWords.dw3 = 0; 182 pResult->DWords.dw2 = uTmp.DWords.dw1; 183 pResult->DWords.dw1 += uTmp.DWords.dw0; 184 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 185 if (pResult->DWords.dw2++ == UINT32_MAX) 186 pResult->DWords.dw3++; 187 188 pResult->s.Hi += (uint64_t)pValue1->DWords.dw2 * pValue2->DWords.dw0; 189 pResult->DWords.dw3 += pValue1->DWords.dw3 * pValue2->DWords.dw0; 190 191 /* multiply dw0, dw1 & dw2 in v1 by v2.dw1. */ 192 uTmp.u = (uint64_t)pValue1->DWords.dw0 * pValue2->DWords.dw1; 193 pResult->DWords.dw1 += uTmp.DWords.dw0; 194 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 195 if (pResult->DWords.dw2++ == UINT32_MAX) 196 pResult->DWords.dw3++; 197 198 pResult->DWords.dw2 += uTmp.DWords.dw1; 199 if (pResult->DWords.dw2 < uTmp.DWords.dw1) 200 pResult->DWords.dw3++; 201 202 pResult->s.Hi += (uint64_t)pValue1->DWords.dw1 * pValue2->DWords.dw1; 203 pResult->DWords.dw3 += pValue1->DWords.dw2 * pValue2->DWords.dw1; 204 205 /* multiply dw0 & dw1 in v1 by v2.dw2. */ 206 pResult->s.Hi += (uint64_t)pValue1->DWords.dw0 * pValue2->DWords.dw2; 207 pResult->DWords.dw3 += pValue1->DWords.dw1 * pValue2->DWords.dw2; 208 209 /* multiply dw0 in v1 by v2.dw3. */ 210 pResult->DWords.dw3 += pValue1->DWords.dw0 * pValue2->DWords.dw3; 211 212 return pResult; 213 } 214 215 216 /** 217 * Multiplies an 128-bit unsigned integer by a 64-bit unsigned integer value. 209 RTDECL(PRTUINT256U) RTUInt256Mul(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2); 210 211 /** 212 * Multiplies an 256-bit unsigned integer by a 64-bit unsigned integer value. 218 213 * 219 214 * @returns pResult … … 222 217 * @param uValue2 The second value, 64-bit. 223 218 */ 224 #if defined(RT_ARCH_AMD64) 225 RTDECL(PRTUINT128U) RTUInt128MulByU64(PRTUINT128U pResult, PCRTUINT128U pValue1, uint64_t uValue2); 226 #else 227 DECLINLINE(PRTUINT128U) RTUInt128MulByU64(PRTUINT128U pResult, PCRTUINT128U pValue1, uint64_t uValue2) 228 { 229 uint32_t const uLoValue2 = (uint32_t)uValue2; 230 uint32_t const uHiValue2 = (uint32_t)(uValue2 >> 32); 231 RTUINT64U uTmp; 232 233 /* multiply all dwords in v1 by uLoValue1. */ 234 pResult->s.Lo = (uint64_t)pValue1->DWords.dw0 * uLoValue2; 235 236 uTmp.u = (uint64_t)pValue1->DWords.dw1 * uLoValue2; 237 pResult->DWords.dw3 = 0; 238 pResult->DWords.dw2 = uTmp.DWords.dw1; 239 pResult->DWords.dw1 += uTmp.DWords.dw0; 240 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 241 if (pResult->DWords.dw2++ == UINT32_MAX) 242 pResult->DWords.dw3++; 243 244 pResult->s.Hi += (uint64_t)pValue1->DWords.dw2 * uLoValue2; 245 pResult->DWords.dw3 += pValue1->DWords.dw3 * uLoValue2; 246 247 /* multiply dw0, dw1 & dw2 in v1 by uHiValue2. */ 248 uTmp.u = (uint64_t)pValue1->DWords.dw0 * uHiValue2; 249 pResult->DWords.dw1 += uTmp.DWords.dw0; 250 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 251 if (pResult->DWords.dw2++ == UINT32_MAX) 252 pResult->DWords.dw3++; 253 254 pResult->DWords.dw2 += uTmp.DWords.dw1; 255 if (pResult->DWords.dw2 < uTmp.DWords.dw1) 256 pResult->DWords.dw3++; 257 258 pResult->s.Hi += (uint64_t)pValue1->DWords.dw1 * uHiValue2; 259 pResult->DWords.dw3 += pValue1->DWords.dw2 * uHiValue2; 260 261 return pResult; 262 } 263 #endif 264 265 266 /** 267 * Multiplies two 64-bit unsigned integer values with 128-bit precision. 268 * 269 * @returns pResult 270 * @param pResult The result variable. 271 * @param uValue1 The first value. 64-bit. 272 * @param uValue2 The second value, 64-bit. 273 */ 274 DECLINLINE(PRTUINT128U) RTUInt128MulU64ByU64(PRTUINT128U pResult, uint64_t uValue1, uint64_t uValue2) 275 { 276 #ifdef RT_ARCH_AMD64 277 pResult->s.Lo = ASMMult2xU64Ret2xU64(uValue1, uValue2, &pResult->s.Hi); 278 #else 279 uint32_t const uLoValue1 = (uint32_t)uValue1; 280 uint32_t const uHiValue1 = (uint32_t)(uValue1 >> 32); 281 uint32_t const uLoValue2 = (uint32_t)uValue2; 282 uint32_t const uHiValue2 = (uint32_t)(uValue2 >> 32); 283 RTUINT64U uTmp; 284 285 /* Multiply uLoValue1 and uHiValue1 by uLoValue1. */ 286 pResult->s.Lo = (uint64_t)uLoValue1 * uLoValue2; 287 288 uTmp.u = (uint64_t)uHiValue1 * uLoValue2; 289 pResult->DWords.dw3 = 0; 290 pResult->DWords.dw2 = uTmp.DWords.dw1; 291 pResult->DWords.dw1 += uTmp.DWords.dw0; 292 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 293 if (pResult->DWords.dw2++ == UINT32_MAX) 294 pResult->DWords.dw3++; 295 296 /* Multiply uLoValue1 and uHiValue1 by uHiValue2. */ 297 uTmp.u = (uint64_t)uLoValue1 * uHiValue2; 298 pResult->DWords.dw1 += uTmp.DWords.dw0; 299 if (pResult->DWords.dw1 < uTmp.DWords.dw0) 300 if (pResult->DWords.dw2++ == UINT32_MAX) 301 pResult->DWords.dw3++; 302 303 pResult->DWords.dw2 += uTmp.DWords.dw1; 304 if (pResult->DWords.dw2 < uTmp.DWords.dw1) 305 pResult->DWords.dw3++; 306 307 pResult->s.Hi += (uint64_t)uHiValue1 * uHiValue2; 308 #endif 309 return pResult; 310 } 311 312 313 DECLINLINE(PRTUINT128U) RTUInt128DivRem(PRTUINT128U pQuotient, PRTUINT128U pRemainder, PCRTUINT128U pValue1, PCRTUINT128U pValue2); 314 315 /** 316 * Divides a 128-bit unsigned integer value by another. 317 * 318 * @returns pResult 319 * @param pResult The result variable. 320 * @param pValue1 The dividend value. 321 * @param pValue2 The divisor value. 322 */ 323 DECLINLINE(PRTUINT128U) RTUInt128Div(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 324 { 325 RTUINT128U Ignored; 326 return RTUInt128DivRem(pResult, &Ignored, pValue1, pValue2); 327 } 328 329 330 /** 331 * Divides a 128-bit unsigned integer value by another, returning the remainder. 332 * 333 * @returns pResult 334 * @param pResult The result variable (remainder). 335 * @param pValue1 The dividend value. 336 * @param pValue2 The divisor value. 337 */ 338 DECLINLINE(PRTUINT128U) RTUInt128Mod(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 339 { 340 RTUINT128U Ignored; 341 RTUInt128DivRem(&Ignored, pResult, pValue1, pValue2); 342 return pResult; 343 } 344 345 346 /** 347 * Bitwise AND of two 128-bit unsigned integer values. 348 * 349 * @returns pResult 350 * @param pResult The result variable. 351 * @param pValue1 The first value. 352 * @param pValue2 The second value. 353 */ 354 DECLINLINE(PRTUINT128U) RTUInt128And(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 355 { 356 pResult->s.Hi = pValue1->s.Hi & pValue2->s.Hi; 357 pResult->s.Lo = pValue1->s.Lo & pValue2->s.Lo; 358 return pResult; 359 } 360 361 362 /** 363 * Bitwise OR of two 128-bit unsigned integer values. 364 * 365 * @returns pResult 366 * @param pResult The result variable. 367 * @param pValue1 The first value. 368 * @param pValue2 The second value. 369 */ 370 DECLINLINE(PRTUINT128U) RTUInt128Or( PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 371 { 372 pResult->s.Hi = pValue1->s.Hi | pValue2->s.Hi; 373 pResult->s.Lo = pValue1->s.Lo | pValue2->s.Lo; 374 return pResult; 375 } 376 377 378 /** 379 * Bitwise XOR of two 128-bit unsigned integer values. 380 * 381 * @returns pResult 382 * @param pResult The result variable. 383 * @param pValue1 The first value. 384 * @param pValue2 The second value. 385 */ 386 DECLINLINE(PRTUINT128U) RTUInt128Xor(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 387 { 388 pResult->s.Hi = pValue1->s.Hi ^ pValue2->s.Hi; 389 pResult->s.Lo = pValue1->s.Lo ^ pValue2->s.Lo; 390 return pResult; 391 } 392 393 394 /** 395 * Shifts a 128-bit unsigned integer value @a cBits to the left. 396 * 397 * @returns pResult 398 * @param pResult The result variable. 399 * @param pValue The value to shift. 400 * @param cBits The number of bits to shift it. 401 */ 402 DECLINLINE(PRTUINT128U) RTUInt128ShiftLeft(PRTUINT128U pResult, PCRTUINT128U pValue, int cBits) 403 { 404 cBits &= 127; 405 if (cBits < 64) 406 { 407 pResult->s.Lo = pValue->s.Lo << cBits; 408 pResult->s.Hi = (pValue->s.Hi << cBits) | (pValue->s.Lo >> (64 - cBits)); 409 } 410 else 411 { 412 pResult->s.Lo = 0; 413 pResult->s.Hi = pValue->s.Lo << (cBits - 64); 414 } 415 return pResult; 416 } 417 418 419 /** 420 * Shifts a 128-bit unsigned integer value @a cBits to the right. 421 * 422 * @returns pResult 423 * @param pResult The result variable. 424 * @param pValue The value to shift. 425 * @param cBits The number of bits to shift it. 426 */ 427 DECLINLINE(PRTUINT128U) RTUInt128ShiftRight(PRTUINT128U pResult, PCRTUINT128U pValue, int cBits) 428 { 429 cBits &= 127; 430 if (cBits < 64) 431 { 432 pResult->s.Hi = pValue->s.Hi >> cBits; 433 pResult->s.Lo = (pValue->s.Lo >> cBits) | (pValue->s.Hi << (64 - cBits)); 434 } 435 else 436 { 437 pResult->s.Hi = 0; 438 pResult->s.Lo = pValue->s.Hi >> (cBits - 64); 439 } 440 return pResult; 441 } 442 443 444 /** 445 * Boolean not (result 0 or 1). 446 * 447 * @returns pResult. 448 * @param pResult The result variable. 449 * @param pValue The value. 450 */ 451 DECLINLINE(PRTUINT128U) RTUInt128BooleanNot(PRTUINT128U pResult, PCRTUINT128U pValue) 452 { 453 pResult->s.Lo = pValue->s.Lo || pValue->s.Hi ? 0 : 1; 454 pResult->s.Hi = 0; 455 return pResult; 456 } 457 458 459 /** 460 * Bitwise not (flips each bit of the 128 bits). 461 * 462 * @returns pResult. 463 * @param pResult The result variable. 464 * @param pValue The value. 465 */ 466 DECLINLINE(PRTUINT128U) RTUInt128BitwiseNot(PRTUINT128U pResult, PCRTUINT128U pValue) 467 { 468 pResult->s.Hi = ~pValue->s.Hi; 469 pResult->s.Lo = ~pValue->s.Lo; 470 return pResult; 471 } 472 473 474 /** 475 * Assigns one 128-bit unsigned integer value to another. 476 * 477 * @returns pResult 478 * @param pResult The result variable. 479 * @param pValue The value to assign. 480 */ 481 DECLINLINE(PRTUINT128U) RTUInt128Assign(PRTUINT128U pResult, PCRTUINT128U pValue) 482 { 483 #if ARCH_BITS >= 64 484 pResult->s.Hi = pValue->s.Hi; 485 pResult->s.Lo = pValue->s.Lo; 486 #else 487 pResult->DWords.dw0 = pValue->DWords.dw0; 488 pResult->DWords.dw1 = pValue->DWords.dw1; 489 pResult->DWords.dw2 = pValue->DWords.dw2; 490 pResult->DWords.dw3 = pValue->DWords.dw3; 491 #endif 492 return pResult; 493 } 494 495 496 /** 497 * Assigns a boolean value to 128-bit unsigned integer. 498 * 499 * @returns pValueResult 500 * @param pValueResult The result variable. 501 * @param fValue The boolean value. 502 */ 503 DECLINLINE(PRTUINT128U) RTUInt128AssignBoolean(PRTUINT128U pValueResult, bool fValue) 504 { 505 #if ARCH_BITS >= 64 506 pValueResult->s.Lo = fValue; 507 pValueResult->s.Hi = 0; 508 #else 509 pValueResult->DWords.dw0 = fValue; 510 pValueResult->DWords.dw1 = 0; 511 pValueResult->DWords.dw2 = 0; 512 pValueResult->DWords.dw3 = 0; 513 #endif 514 return pValueResult; 515 } 516 517 518 /** 519 * Assigns a 8-bit unsigned integer value to 128-bit unsigned integer. 520 * 521 * @returns pValueResult 522 * @param pValueResult The result variable. 523 * @param u8Value The 8-bit unsigned integer value. 524 */ 525 DECLINLINE(PRTUINT128U) RTUInt128AssignU8(PRTUINT128U pValueResult, uint8_t u8Value) 526 { 527 #if ARCH_BITS >= 64 528 pValueResult->s.Lo = u8Value; 529 pValueResult->s.Hi = 0; 530 #else 531 pValueResult->DWords.dw0 = u8Value; 532 pValueResult->DWords.dw1 = 0; 533 pValueResult->DWords.dw2 = 0; 534 pValueResult->DWords.dw3 = 0; 535 #endif 536 return pValueResult; 537 } 538 539 540 /** 541 * Assigns a 16-bit unsigned integer value to 128-bit unsigned integer. 542 * 543 * @returns pValueResult 544 * @param pValueResult The result variable. 545 * @param u16Value The 16-bit unsigned integer value. 546 */ 547 DECLINLINE(PRTUINT128U) RTUInt128AssignU16(PRTUINT128U pValueResult, uint16_t u16Value) 548 { 549 #if ARCH_BITS >= 64 550 pValueResult->s.Lo = u16Value; 551 pValueResult->s.Hi = 0; 552 #else 553 pValueResult->DWords.dw0 = u16Value; 554 pValueResult->DWords.dw1 = 0; 555 pValueResult->DWords.dw2 = 0; 556 pValueResult->DWords.dw3 = 0; 557 #endif 558 return pValueResult; 559 } 560 561 562 /** 563 * Assigns a 32-bit unsigned integer value to 128-bit unsigned integer. 564 * 565 * @returns pValueResult 566 * @param pValueResult The result variable. 567 * @param u32Value The 32-bit unsigned integer value. 568 */ 569 DECLINLINE(PRTUINT128U) RTUInt128AssignU32(PRTUINT128U pValueResult, uint32_t u32Value) 570 { 571 #if ARCH_BITS >= 64 572 pValueResult->s.Lo = u32Value; 573 pValueResult->s.Hi = 0; 574 #else 575 pValueResult->DWords.dw0 = u32Value; 576 pValueResult->DWords.dw1 = 0; 577 pValueResult->DWords.dw2 = 0; 578 pValueResult->DWords.dw3 = 0; 579 #endif 580 return pValueResult; 581 } 582 583 584 /** 585 * Assigns a 64-bit unsigned integer value to 128-bit unsigned integer. 586 * 587 * @returns pValueResult 588 * @param pValueResult The result variable. 589 * @param u64Value The 64-bit unsigned integer value. 590 */ 591 DECLINLINE(PRTUINT128U) RTUInt128AssignU64(PRTUINT128U pValueResult, uint64_t u64Value) 592 { 593 pValueResult->s.Lo = u64Value; 594 pValueResult->s.Hi = 0; 595 return pValueResult; 596 } 597 598 599 /** 600 * Adds two 128-bit unsigned integer values, storing the result in the first. 601 * 602 * @returns pValue1Result. 603 * @param pValue1Result The first value and result. 604 * @param pValue2 The second value. 605 */ 606 DECLINLINE(PRTUINT128U) RTUInt128AssignAdd(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 607 { 608 uint64_t const uTmp = pValue1Result->s.Lo; 609 pValue1Result->s.Lo += pValue2->s.Lo; 610 if (pValue1Result->s.Lo < uTmp) 611 pValue1Result->s.Hi++; 612 pValue1Result->s.Hi += pValue2->s.Hi; 613 return pValue1Result; 614 } 615 616 617 /** 618 * Adds a 64-bit unsigned integer value to a 128-bit unsigned integer values, 619 * storing the result in the 128-bit one. 620 * 621 * @returns pValue1Result. 622 * @param pValue1Result The first value and result. 623 * @param uValue2 The second value, 64-bit. 624 */ 625 DECLINLINE(PRTUINT128U) RTUInt128AssignAddU64(PRTUINT128U pValue1Result, uint64_t uValue2) 626 { 627 pValue1Result->s.Lo += uValue2; 628 if (pValue1Result->s.Lo < uValue2) 629 pValue1Result->s.Hi++; 630 return pValue1Result; 631 } 632 633 634 /** 635 * Subtracts two 128-bit unsigned integer values, storing the result in the 636 * first. 637 * 638 * @returns pValue1Result. 639 * @param pValue1Result The minuend value and result. 640 * @param pValue2 The subtrahend value. 641 */ 642 DECLINLINE(PRTUINT128U) RTUInt128AssignSub(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 643 { 644 uint64_t const uTmp = pValue1Result->s.Lo; 645 pValue1Result->s.Lo -= pValue2->s.Lo; 646 if (pValue1Result->s.Lo > uTmp) 647 pValue1Result->s.Hi--; 648 pValue1Result->s.Hi -= pValue2->s.Hi; 649 return pValue1Result; 650 } 651 652 653 /** 654 * Negates a 128 number, storing the result in the input. 655 * 656 * @returns pValueResult. 657 * @param pValueResult The value to negate. 658 */ 659 DECLINLINE(PRTUINT128U) RTUInt128AssignNeg(PRTUINT128U pValueResult) 660 { 661 /* result = 0 - value */ 662 if (pValueResult->s.Lo != 0) 663 { 664 pValueResult->s.Lo = UINT64_C(0) - pValueResult->s.Lo; 665 pValueResult->s.Hi = UINT64_MAX - pValueResult->s.Hi; 666 } 667 else 668 pValueResult->s.Hi = UINT64_C(0) - pValueResult->s.Hi; 669 return pValueResult; 670 } 671 672 673 /** 674 * Multiplies two 128-bit unsigned integer values, storing the result in the 675 * first. 676 * 677 * @returns pValue1Result. 678 * @param pValue1Result The first value and result. 679 * @param pValue2 The second value. 680 */ 681 DECLINLINE(PRTUINT128U) RTUInt128AssignMul(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 682 { 683 RTUINT128U Result; 684 RTUInt128Mul(&Result, pValue1Result, pValue2); 685 *pValue1Result = Result; 686 return pValue1Result; 687 } 688 689 690 /** 691 * Divides a 128-bit unsigned integer value by another, storing the result in 692 * the first. 693 * 694 * @returns pValue1Result. 695 * @param pValue1Result The dividend value and result. 696 * @param pValue2 The divisor value. 697 */ 698 DECLINLINE(PRTUINT128U) RTUInt128AssignDiv(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 699 { 700 RTUINT128U Result; 701 RTUINT128U Ignored; 702 RTUInt128DivRem(&Result, &Ignored, pValue1Result, pValue2); 703 *pValue1Result = Result; 704 return pValue1Result; 705 } 706 707 708 /** 709 * Divides a 128-bit unsigned integer value by another, storing the remainder in 710 * the first. 711 * 712 * @returns pValue1Result. 713 * @param pValue1Result The dividend value and result (remainder). 714 * @param pValue2 The divisor value. 715 */ 716 DECLINLINE(PRTUINT128U) RTUInt128AssignMod(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 717 { 718 RTUINT128U Ignored; 719 RTUINT128U Result; 720 RTUInt128DivRem(&Ignored, &Result, pValue1Result, pValue2); 721 *pValue1Result = Result; 722 return pValue1Result; 723 } 724 725 726 /** 727 * Performs a bitwise AND of two 128-bit unsigned integer values and assigned 728 * the result to the first one. 729 * 730 * @returns pValue1Result. 731 * @param pValue1Result The first value and result. 732 * @param pValue2 The second value. 733 */ 734 DECLINLINE(PRTUINT128U) RTUInt128AssignAnd(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 735 { 736 #if ARCH_BITS >= 64 737 pValue1Result->s.Hi &= pValue2->s.Hi; 738 pValue1Result->s.Lo &= pValue2->s.Lo; 739 #else 740 pValue1Result->DWords.dw0 &= pValue2->DWords.dw0; 741 pValue1Result->DWords.dw1 &= pValue2->DWords.dw1; 742 pValue1Result->DWords.dw2 &= pValue2->DWords.dw2; 743 pValue1Result->DWords.dw3 &= pValue2->DWords.dw3; 744 #endif 745 return pValue1Result; 746 } 747 748 749 /** 750 * Performs a bitwise AND of a 128-bit unsigned integer value and a mask made 751 * up of the first N bits, assigning the result to the the 128-bit value. 752 * 753 * @returns pValueResult. 754 * @param pValueResult The value and result. 755 * @param cBits The number of bits to AND (counting from the first 756 * bit). 757 */ 758 DECLINLINE(PRTUINT128U) RTUInt128AssignAndNFirstBits(PRTUINT128U pValueResult, unsigned cBits) 759 { 760 if (cBits <= 64) 761 { 762 if (cBits != 64) 763 pValueResult->s.Lo &= (RT_BIT_64(cBits) - 1); 764 pValueResult->s.Hi = 0; 765 } 766 else if (cBits < 128) 767 pValueResult->s.Hi &= (RT_BIT_64(cBits - 64) - 1); 768 /** @todo \#if ARCH_BITS >= 64 */ 769 return pValueResult; 770 } 771 772 773 /** 774 * Performs a bitwise OR of two 128-bit unsigned integer values and assigned 775 * the result to the first one. 776 * 777 * @returns pValue1Result. 778 * @param pValue1Result The first value and result. 779 * @param pValue2 The second value. 780 */ 781 DECLINLINE(PRTUINT128U) RTUInt128AssignOr(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 782 { 783 #if ARCH_BITS >= 64 784 pValue1Result->s.Hi |= pValue2->s.Hi; 785 pValue1Result->s.Lo |= pValue2->s.Lo; 786 #else 787 pValue1Result->DWords.dw0 |= pValue2->DWords.dw0; 788 pValue1Result->DWords.dw1 |= pValue2->DWords.dw1; 789 pValue1Result->DWords.dw2 |= pValue2->DWords.dw2; 790 pValue1Result->DWords.dw3 |= pValue2->DWords.dw3; 791 #endif 792 return pValue1Result; 793 } 794 795 796 /** 797 * ORs in a bit and assign the result to the input value. 798 * 799 * @returns pValue1Result. 800 * @param pValue1Result The first value and result. 801 * @param iBit The bit to set (0 based). 802 */ 803 DECLINLINE(PRTUINT128U) RTUInt128AssignOrBit(PRTUINT128U pValue1Result, uint32_t iBit) 804 { 805 #if ARCH_BITS >= 64 806 if (iBit >= 64) 807 pValue1Result->s.Hi |= RT_BIT_64(iBit - 64); 808 else 809 pValue1Result->s.Lo |= RT_BIT_64(iBit); 810 #else 811 if (iBit >= 64) 812 { 813 if (iBit >= 96) 814 pValue1Result->DWords.dw3 |= RT_BIT_32(iBit - 96); 815 else 816 pValue1Result->DWords.dw2 |= RT_BIT_32(iBit - 64); 817 } 818 else 819 { 820 if (iBit >= 32) 821 pValue1Result->DWords.dw1 |= RT_BIT_32(iBit - 32); 822 else 823 pValue1Result->DWords.dw0 |= RT_BIT_32(iBit); 824 } 825 #endif 826 return pValue1Result; 827 } 828 829 830 831 /** 832 * Performs a bitwise XOR of two 128-bit unsigned integer values and assigned 833 * the result to the first one. 834 * 835 * @returns pValue1Result. 836 * @param pValue1Result The first value and result. 837 * @param pValue2 The second value. 838 */ 839 DECLINLINE(PRTUINT128U) RTUInt128AssignXor(PRTUINT128U pValue1Result, PCRTUINT128U pValue2) 840 { 841 #if ARCH_BITS >= 64 842 pValue1Result->s.Hi ^= pValue2->s.Hi; 843 pValue1Result->s.Lo ^= pValue2->s.Lo; 844 #else 845 pValue1Result->DWords.dw0 ^= pValue2->DWords.dw0; 846 pValue1Result->DWords.dw1 ^= pValue2->DWords.dw1; 847 pValue1Result->DWords.dw2 ^= pValue2->DWords.dw2; 848 pValue1Result->DWords.dw3 ^= pValue2->DWords.dw3; 849 #endif 850 return pValue1Result; 851 } 852 853 854 /** 855 * Performs a bitwise left shift on a 128-bit unsigned integer value, assigning 856 * the result to it. 857 * 858 * @returns pValueResult. 859 * @param pValueResult The first value and result. 860 * @param cBits The number of bits to shift. 861 */ 862 DECLINLINE(PRTUINT128U) RTUInt128AssignShiftLeft(PRTUINT128U pValueResult, int cBits) 863 { 864 RTUINT128U const InVal = *pValueResult; 865 /** @todo \#if ARCH_BITS >= 64 */ 866 if (cBits > 0) 867 { 868 /* (left shift) */ 869 if (cBits >= 128) 870 RTUInt128SetZero(pValueResult); 871 else if (cBits >= 64) 872 { 873 pValueResult->s.Lo = 0; 874 pValueResult->s.Hi = InVal.s.Lo << (cBits - 64); 875 } 876 else 877 { 878 pValueResult->s.Hi = InVal.s.Hi << cBits; 879 pValueResult->s.Hi |= InVal.s.Lo >> (64 - cBits); 880 pValueResult->s.Lo = InVal.s.Lo << cBits; 881 } 882 } 883 else if (cBits < 0) 884 { 885 /* (right shift) */ 886 cBits = -cBits; 887 if (cBits >= 128) 888 RTUInt128SetZero(pValueResult); 889 else if (cBits >= 64) 890 { 891 pValueResult->s.Hi = 0; 892 pValueResult->s.Lo = InVal.s.Hi >> (cBits - 64); 893 } 894 else 895 { 896 pValueResult->s.Lo = InVal.s.Lo >> cBits; 897 pValueResult->s.Lo |= InVal.s.Hi << (64 - cBits); 898 pValueResult->s.Hi = InVal.s.Hi >> cBits; 899 } 900 } 901 return pValueResult; 902 } 903 904 905 /** 906 * Performs a bitwise left shift on a 128-bit unsigned integer value, assigning 907 * the result to it. 908 * 909 * @returns pValueResult. 910 * @param pValueResult The first value and result. 911 * @param cBits The number of bits to shift. 912 */ 913 DECLINLINE(PRTUINT128U) RTUInt128AssignShiftRight(PRTUINT128U pValueResult, int cBits) 914 { 915 return RTUInt128AssignShiftLeft(pValueResult, -cBits); 916 } 917 918 919 /** 920 * Performs a bitwise NOT on a 128-bit unsigned integer value, assigning the 921 * result to it. 922 * 923 * @returns pValueResult 924 * @param pValueResult The value and result. 925 */ 926 DECLINLINE(PRTUINT128U) RTUInt128AssignBitwiseNot(PRTUINT128U pValueResult) 927 { 928 #if ARCH_BITS >= 64 929 pValueResult->s.Hi = ~pValueResult->s.Hi; 930 pValueResult->s.Lo = ~pValueResult->s.Lo; 931 #else 932 pValueResult->DWords.dw0 = ~pValueResult->DWords.dw0; 933 pValueResult->DWords.dw1 = ~pValueResult->DWords.dw1; 934 pValueResult->DWords.dw2 = ~pValueResult->DWords.dw2; 935 pValueResult->DWords.dw3 = ~pValueResult->DWords.dw3; 936 #endif 937 return pValueResult; 938 } 939 940 941 /** 942 * Performs a boolean NOT on a 128-bit unsigned integer value, assigning the 943 * result to it. 944 * 945 * @returns pValueResult 946 * @param pValueResult The value and result. 947 */ 948 DECLINLINE(PRTUINT128U) RTUInt128AssignBooleanNot(PRTUINT128U pValueResult) 949 { 950 return RTUInt128AssignBoolean(pValueResult, RTUInt128IsZero(pValueResult)); 951 } 952 953 954 /** 955 * Compares two 128-bit unsigned integer values. 956 * 957 * @retval 0 if equal. 958 * @retval -1 if the first value is smaller than the second. 959 * @retval 1 if the first value is larger than the second. 960 * 961 * @param pValue1 The first value. 962 * @param pValue2 The second value. 963 */ 964 DECLINLINE(int) RTUInt128Compare(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 965 { 966 #if ARCH_BITS >= 64 967 if (pValue1->s.Hi != pValue2->s.Hi) 968 return pValue1->s.Hi > pValue2->s.Hi ? 1 : -1; 969 if (pValue1->s.Lo != pValue2->s.Lo) 970 return pValue1->s.Lo > pValue2->s.Lo ? 1 : -1; 971 return 0; 972 #else 973 if (pValue1->DWords.dw3 != pValue2->DWords.dw3) 974 return pValue1->DWords.dw3 > pValue2->DWords.dw3 ? 1 : -1; 975 if (pValue1->DWords.dw2 != pValue2->DWords.dw2) 976 return pValue1->DWords.dw2 > pValue2->DWords.dw2 ? 1 : -1; 977 if (pValue1->DWords.dw1 != pValue2->DWords.dw1) 978 return pValue1->DWords.dw1 > pValue2->DWords.dw1 ? 1 : -1; 979 if (pValue1->DWords.dw0 != pValue2->DWords.dw0) 980 return pValue1->DWords.dw0 > pValue2->DWords.dw0 ? 1 : -1; 981 return 0; 982 #endif 983 } 984 985 986 /** 987 * Tests if a 128-bit unsigned integer value is smaller than another. 988 * 989 * @returns true if the first value is smaller, false if not. 990 * @param pValue1 The first value. 991 * @param pValue2 The second value. 992 */ 993 DECLINLINE(bool) RTUInt128IsSmaller(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 994 { 995 #if ARCH_BITS >= 64 996 return pValue1->s.Hi < pValue2->s.Hi 997 || ( pValue1->s.Hi == pValue2->s.Hi 998 && pValue1->s.Lo < pValue2->s.Lo); 999 #else 1000 return pValue1->DWords.dw3 < pValue2->DWords.dw3 1001 || ( pValue1->DWords.dw3 == pValue2->DWords.dw3 1002 && ( pValue1->DWords.dw2 < pValue2->DWords.dw2 1003 || ( pValue1->DWords.dw2 == pValue2->DWords.dw2 1004 && ( pValue1->DWords.dw1 < pValue2->DWords.dw1 1005 || ( pValue1->DWords.dw1 == pValue2->DWords.dw1 1006 && pValue1->DWords.dw0 < pValue2->DWords.dw0))))); 1007 #endif 1008 } 1009 1010 1011 /** 1012 * Tests if a 128-bit unsigned integer value is larger than another. 1013 * 1014 * @returns true if the first value is larger, false if not. 1015 * @param pValue1 The first value. 1016 * @param pValue2 The second value. 1017 */ 1018 DECLINLINE(bool) RTUInt128IsLarger(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 1019 { 1020 #if ARCH_BITS >= 64 1021 return pValue1->s.Hi > pValue2->s.Hi 1022 || ( pValue1->s.Hi == pValue2->s.Hi 1023 && pValue1->s.Lo > pValue2->s.Lo); 1024 #else 1025 return pValue1->DWords.dw3 > pValue2->DWords.dw3 1026 || ( pValue1->DWords.dw3 == pValue2->DWords.dw3 1027 && ( pValue1->DWords.dw2 > pValue2->DWords.dw2 1028 || ( pValue1->DWords.dw2 == pValue2->DWords.dw2 1029 && ( pValue1->DWords.dw1 > pValue2->DWords.dw1 1030 || ( pValue1->DWords.dw1 == pValue2->DWords.dw1 1031 && pValue1->DWords.dw0 > pValue2->DWords.dw0))))); 1032 #endif 1033 } 1034 1035 1036 /** 1037 * Tests if a 128-bit unsigned integer value is larger or equal than another. 1038 * 1039 * @returns true if the first value is larger or equal, false if not. 1040 * @param pValue1 The first value. 1041 * @param pValue2 The second value. 1042 */ 1043 DECLINLINE(bool) RTUInt128IsLargerOrEqual(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 1044 { 1045 #if ARCH_BITS >= 64 1046 return pValue1->s.Hi > pValue2->s.Hi 1047 || ( pValue1->s.Hi == pValue2->s.Hi 1048 && pValue1->s.Lo >= pValue2->s.Lo); 1049 #else 1050 return pValue1->DWords.dw3 > pValue2->DWords.dw3 1051 || ( pValue1->DWords.dw3 == pValue2->DWords.dw3 1052 && ( pValue1->DWords.dw2 > pValue2->DWords.dw2 1053 || ( pValue1->DWords.dw2 == pValue2->DWords.dw2 1054 && ( pValue1->DWords.dw1 > pValue2->DWords.dw1 1055 || ( pValue1->DWords.dw1 == pValue2->DWords.dw1 1056 && pValue1->DWords.dw0 >= pValue2->DWords.dw0))))); 1057 #endif 1058 } 1059 1060 1061 /** 1062 * Tests if two 128-bit unsigned integer values not equal. 1063 * 1064 * @returns true if equal, false if not equal. 1065 * @param pValue1 The first value. 1066 * @param pValue2 The second value. 1067 */ 1068 DECLINLINE(bool) RTUInt128IsEqual(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 1069 { 1070 #if ARCH_BITS >= 64 1071 return pValue1->s.Hi == pValue2->s.Hi 1072 && pValue1->s.Lo == pValue2->s.Lo; 1073 #else 1074 return pValue1->DWords.dw0 == pValue2->DWords.dw0 1075 && pValue1->DWords.dw1 == pValue2->DWords.dw1 1076 && pValue1->DWords.dw2 == pValue2->DWords.dw2 1077 && pValue1->DWords.dw3 == pValue2->DWords.dw3; 1078 #endif 1079 } 1080 1081 1082 /** 1083 * Tests if two 128-bit unsigned integer values are not equal. 1084 * 1085 * @returns true if not equal, false if equal. 1086 * @param pValue1 The first value. 1087 * @param pValue2 The second value. 1088 */ 1089 DECLINLINE(bool) RTUInt128IsNotEqual(PCRTUINT128U pValue1, PCRTUINT128U pValue2) 1090 { 1091 return !RTUInt128IsEqual(pValue1, pValue2); 1092 } 1093 1094 1095 /** 1096 * Sets a bit in a 128-bit unsigned integer type. 1097 * 1098 * @returns pValueResult. 1099 * @param pValueResult The input and output value. 1100 * @param iBit The bit to set. 1101 */ 1102 DECLINLINE(PRTUINT128U) RTUInt128BitSet(PRTUINT128U pValueResult, unsigned iBit) 1103 { 1104 if (iBit < 64) 1105 { 1106 #if ARCH_BITS >= 64 1107 pValueResult->s.Lo |= RT_BIT_64(iBit); 1108 #else 1109 if (iBit < 32) 1110 pValueResult->DWords.dw0 |= RT_BIT_32(iBit); 1111 else 1112 pValueResult->DWords.dw1 |= RT_BIT_32(iBit - 32); 1113 #endif 1114 } 1115 else if (iBit < 128) 1116 { 1117 #if ARCH_BITS >= 64 1118 pValueResult->s.Hi |= RT_BIT_64(iBit - 64); 1119 #else 1120 if (iBit < 96) 1121 pValueResult->DWords.dw2 |= RT_BIT_32(iBit - 64); 1122 else 1123 pValueResult->DWords.dw3 |= RT_BIT_32(iBit - 96); 1124 #endif 1125 } 1126 return pValueResult; 1127 } 1128 1129 1130 /** 1131 * Sets a bit in a 128-bit unsigned integer type. 1132 * 1133 * @returns pValueResult. 1134 * @param pValueResult The input and output value. 1135 * @param iBit The bit to set. 1136 */ 1137 DECLINLINE(PRTUINT128U) RTUInt128BitClear(PRTUINT128U pValueResult, unsigned iBit) 1138 { 1139 if (iBit < 64) 1140 { 1141 #if ARCH_BITS >= 64 1142 pValueResult->s.Lo &= ~RT_BIT_64(iBit); 1143 #else 1144 if (iBit < 32) 1145 pValueResult->DWords.dw0 &= ~RT_BIT_32(iBit); 1146 else 1147 pValueResult->DWords.dw1 &= ~RT_BIT_32(iBit - 32); 1148 #endif 1149 } 1150 else if (iBit < 128) 1151 { 1152 #if ARCH_BITS >= 64 1153 pValueResult->s.Hi &= ~RT_BIT_64(iBit - 64); 1154 #else 1155 if (iBit < 96) 1156 pValueResult->DWords.dw2 &= ~RT_BIT_32(iBit - 64); 1157 else 1158 pValueResult->DWords.dw3 &= ~RT_BIT_32(iBit - 96); 1159 #endif 1160 } 1161 return pValueResult; 1162 } 1163 1164 1165 /** 1166 * Tests if a bit in a 128-bit unsigned integer value is set. 1167 * 1168 * @returns pValueResult. 1169 * @param pValueResult The input and output value. 1170 * @param iBit The bit to test. 1171 */ 1172 DECLINLINE(bool) RTUInt128BitTest(PRTUINT128U pValueResult, unsigned iBit) 1173 { 1174 bool fRc; 1175 if (iBit < 64) 1176 { 1177 #if ARCH_BITS >= 64 1178 fRc = RT_BOOL(pValueResult->s.Lo & RT_BIT_64(iBit)); 1179 #else 1180 if (iBit < 32) 1181 fRc = RT_BOOL(pValueResult->DWords.dw0 & RT_BIT_32(iBit)); 1182 else 1183 fRc = RT_BOOL(pValueResult->DWords.dw1 & RT_BIT_32(iBit - 32)); 1184 #endif 1185 } 1186 else if (iBit < 128) 1187 { 1188 #if ARCH_BITS >= 64 1189 fRc = RT_BOOL(pValueResult->s.Hi & RT_BIT_64(iBit - 64)); 1190 #else 1191 if (iBit < 96) 1192 fRc = RT_BOOL(pValueResult->DWords.dw2 & RT_BIT_32(iBit - 64)); 1193 else 1194 fRc = RT_BOOL(pValueResult->DWords.dw3 & RT_BIT_32(iBit - 96)); 1195 #endif 1196 } 1197 else 1198 fRc = false; 1199 return fRc; 1200 } 1201 1202 1203 /** 1204 * Set a range of bits a 128-bit unsigned integer value. 1205 * 1206 * @returns pValueResult. 1207 * @param pValueResult The input and output value. 1208 * @param iFirstBit The first bit to test. 1209 * @param cBits The number of bits to set. 1210 */ 1211 DECLINLINE(PRTUINT128U) RTUInt128BitSetRange(PRTUINT128U pValueResult, unsigned iFirstBit, unsigned cBits) 1212 { 1213 /* bounds check & fix. */ 1214 if (iFirstBit < 128) 1215 { 1216 if (iFirstBit + cBits > 128) 1217 cBits = 128 - iFirstBit; 1218 1219 #if ARCH_BITS >= 64 1220 if (iFirstBit + cBits < 64) 1221 pValueResult->s.Lo |= (RT_BIT_64(cBits) - 1) << iFirstBit; 1222 else if (iFirstBit + cBits < 128 && iFirstBit >= 64) 1223 pValueResult->s.Hi |= (RT_BIT_64(cBits) - 1) << (iFirstBit - 64); 1224 else 1225 #else 1226 if (iFirstBit + cBits < 32) 1227 pValueResult->DWords.dw0 |= (RT_BIT_32(cBits) - 1) << iFirstBit; 1228 else if (iFirstBit + cBits < 64 && iFirstBit >= 32) 1229 pValueResult->DWords.dw1 |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 32); 1230 else if (iFirstBit + cBits < 96 && iFirstBit >= 64) 1231 pValueResult->DWords.dw2 |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 64); 1232 else if (iFirstBit + cBits < 128 && iFirstBit >= 96) 1233 pValueResult->DWords.dw3 |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 96); 1234 else 1235 #endif 1236 while (cBits-- > 0) 1237 RTUInt128BitSet(pValueResult, iFirstBit++); 1238 } 1239 return pValueResult; 1240 } 1241 1242 1243 /** 1244 * Test if all the bits of a 128-bit unsigned integer value are set. 1245 * 1246 * @returns true if they are, false if they aren't. 1247 * @param pValue The input and output value. 1248 */ 1249 DECLINLINE(bool) RTUInt128BitAreAllSet(PRTUINT128U pValue) 1250 { 1251 #if ARCH_BITS >= 64 1252 return pValue->s.Hi == UINT64_MAX 1253 && pValue->s.Lo == UINT64_MAX; 1254 #else 1255 return pValue->DWords.dw0 == UINT32_MAX 1256 && pValue->DWords.dw1 == UINT32_MAX 1257 && pValue->DWords.dw2 == UINT32_MAX 1258 && pValue->DWords.dw3 == UINT32_MAX; 1259 #endif 1260 } 1261 1262 1263 /** 1264 * Test if all the bits of a 128-bit unsigned integer value are clear. 1265 * 1266 * @returns true if they are, false if they aren't. 1267 * @param pValue The input and output value. 1268 */ 1269 DECLINLINE(bool) RTUInt128BitAreAllClear(PRTUINT128U pValue) 1270 { 1271 #if ARCH_BITS >= 64 1272 return pValue->s.Hi == 0 1273 && pValue->s.Lo == 0; 1274 #else 1275 return pValue->DWords.dw0 == 0 1276 && pValue->DWords.dw1 == 0 1277 && pValue->DWords.dw2 == 0 1278 && pValue->DWords.dw3 == 0; 1279 #endif 1280 } 1281 1282 1283 DECLINLINE(uint32_t) RTUInt128BitCount(PCRTUINT128U pValue) 1284 { 1285 uint32_t cBits; 1286 if (pValue->s.Hi != 0) 1287 { 1288 if (pValue->DWords.dw3) 1289 cBits = 96 + ASMBitLastSetU32(pValue->DWords.dw3); 1290 else 1291 cBits = 64 + ASMBitLastSetU32(pValue->DWords.dw2); 1292 } 1293 else 1294 { 1295 if (pValue->DWords.dw1) 1296 cBits = 32 + ASMBitLastSetU32(pValue->DWords.dw1); 1297 else 1298 cBits = 0 + ASMBitLastSetU32(pValue->DWords.dw0); 1299 } 1300 return cBits; 1301 } 1302 1303 1304 /** 1305 * Divides a 128-bit unsigned integer value by another, returning both quotient 219 RTDECL(PRTUINT256U) RTUInt256MulByU64(PRTUINT256U pResult, PCRTUINT256U pValue1, uint64_t uValue2); 220 221 /** 222 * Divides a 256-bit unsigned integer value by another, returning both quotient 1306 223 * and remainder. 1307 224 * … … 1312 229 * @param pValue2 The divisor value. 1313 230 */ 1314 DECLINLINE(PRTUINT128U) RTUInt128DivRem(PRTUINT128U pQuotient, PRTUINT128U pRemainder, PCRTUINT128U pValue1, PCRTUINT128U pValue2) 1315 { 1316 int iDiff; 1317 1318 /* 1319 * Sort out all the special cases first. 1320 */ 1321 /* Divide by zero or 1? */ 1322 if (!pValue2->s.Hi) 1323 { 1324 if (!pValue2->s.Lo) 1325 return NULL; 1326 1327 if (pValue2->s.Lo == 1) 231 RTDECL(PRTUINT256U) RTUInt256DivRem(PRTUINT256U pQuotient, PRTUINT256U pRemainder, PCRTUINT256U pValue1, PCRTUINT256U pValue2); 232 233 /** 234 * Divides a 256-bit unsigned integer value by another. 235 * 236 * @returns pResult 237 * @param pResult The result variable. 238 * @param pValue1 The dividend value. 239 * @param pValue2 The divisor value. 240 */ 241 DECLINLINE(PRTUINT256U) RTUInt256Div(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2) 242 { 243 RTUINT256U Ignored; 244 return RTUInt256DivRem(pResult, &Ignored, pValue1, pValue2); 245 } 246 247 248 /** 249 * Divides a 256-bit unsigned integer value by another, returning the remainder. 250 * 251 * @returns pResult 252 * @param pResult The result variable (remainder). 253 * @param pValue1 The dividend value. 254 * @param pValue2 The divisor value. 255 */ 256 DECLINLINE(PRTUINT256U) RTUInt256Mod(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2) 257 { 258 RTUINT256U Ignored; 259 RTUInt256DivRem(&Ignored, pResult, pValue1, pValue2); 260 return pResult; 261 } 262 263 264 /** 265 * Bitwise AND of two 256-bit unsigned integer values. 266 * 267 * @returns pResult 268 * @param pResult The result variable. 269 * @param pValue1 The first value. 270 * @param pValue2 The second value. 271 */ 272 DECLINLINE(PRTUINT256U) RTUInt256And(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2) 273 { 274 pResult->QWords.qw0 = pValue1->QWords.qw0 & pValue2->QWords.qw0; 275 pResult->QWords.qw1 = pValue1->QWords.qw1 & pValue2->QWords.qw1; 276 pResult->QWords.qw2 = pValue1->QWords.qw2 & pValue2->QWords.qw2; 277 pResult->QWords.qw3 = pValue1->QWords.qw3 & pValue2->QWords.qw3; 278 return pResult; 279 } 280 281 282 /** 283 * Bitwise OR of two 256-bit unsigned integer values. 284 * 285 * @returns pResult 286 * @param pResult The result variable. 287 * @param pValue1 The first value. 288 * @param pValue2 The second value. 289 */ 290 DECLINLINE(PRTUINT256U) RTUInt256Or( PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2) 291 { 292 pResult->QWords.qw0 = pValue1->QWords.qw0 | pValue2->QWords.qw0; 293 pResult->QWords.qw1 = pValue1->QWords.qw1 | pValue2->QWords.qw1; 294 pResult->QWords.qw2 = pValue1->QWords.qw2 | pValue2->QWords.qw2; 295 pResult->QWords.qw3 = pValue1->QWords.qw3 | pValue2->QWords.qw3; 296 return pResult; 297 } 298 299 300 /** 301 * Bitwise XOR of two 256-bit unsigned integer values. 302 * 303 * @returns pResult 304 * @param pResult The result variable. 305 * @param pValue1 The first value. 306 * @param pValue2 The second value. 307 */ 308 DECLINLINE(PRTUINT256U) RTUInt256Xor(PRTUINT256U pResult, PCRTUINT256U pValue1, PCRTUINT256U pValue2) 309 { 310 pResult->QWords.qw0 = pValue1->QWords.qw0 ^ pValue2->QWords.qw0; 311 pResult->QWords.qw1 = pValue1->QWords.qw1 ^ pValue2->QWords.qw1; 312 pResult->QWords.qw2 = pValue1->QWords.qw2 ^ pValue2->QWords.qw2; 313 pResult->QWords.qw3 = pValue1->QWords.qw3 ^ pValue2->QWords.qw3; 314 return pResult; 315 } 316 317 318 /** 319 * Shifts a 256-bit unsigned integer value @a cBits to the left. 320 * 321 * @returns pResult 322 * @param pResult The result variable. 323 * @param pValue The value to shift. 324 * @param cBits The number of bits to shift it. This is masked 325 * by 255 before shifting. 326 */ 327 DECLINLINE(PRTUINT256U) RTUInt256ShiftLeft(PRTUINT256U pResult, PCRTUINT256U pValue, unsigned cBits) 328 { 329 /* This is a bit bulky & impractical since we cannot access the data using 330 an array because it is organized according to host endianness. Sigh. */ 331 cBits &= 255; 332 if (!(cBits & 0x3f)) 333 { 334 if (cBits == 0) 335 *pResult = *pValue; 336 else 1328 337 { 1329 RTUInt128SetZero(pRemainder); 1330 *pQuotient = *pValue1; 1331 return pQuotient; 1332 } 1333 /** @todo RTUint128DivModBy64 */ 1334 } 1335 1336 /* Dividend is smaller? */ 1337 iDiff = RTUInt128Compare(pValue1, pValue2); 1338 if (iDiff < 0) 1339 { 1340 *pRemainder = *pValue1; 1341 RTUInt128SetZero(pQuotient); 1342 } 1343 1344 /* The values are equal? */ 1345 else if (iDiff == 0) 1346 { 1347 RTUInt128SetZero(pRemainder); 1348 RTUInt128AssignU64(pQuotient, 1); 1349 } 1350 else 1351 { 1352 /* 1353 * Prepare. 1354 */ 1355 uint32_t iBitAdder = RTUInt128BitCount(pValue1) - RTUInt128BitCount(pValue2); 1356 RTUINT128U NormDivisor = *pValue2; 1357 if (iBitAdder) 1358 { 1359 RTUInt128ShiftLeft(&NormDivisor, pValue2, iBitAdder); 1360 if (RTUInt128IsLarger(&NormDivisor, pValue1)) 338 pResult->QWords.qw0 = 0; 339 if (cBits == 64) 1361 340 { 1362 RTUInt128AssignShiftRight(&NormDivisor, 1); 1363 iBitAdder--; 341 pResult->QWords.qw1 = pValue->QWords.qw0; 342 pResult->QWords.qw2 = pValue->QWords.qw1; 343 pResult->QWords.qw3 = pValue->QWords.qw2; 344 } 345 else 346 { 347 pResult->QWords.qw1 = 0; 348 if (cBits == 128) 349 { 350 pResult->QWords.qw2 = pValue->QWords.qw0; 351 pResult->QWords.qw3 = pValue->QWords.qw1; 352 } 353 else 354 { 355 pResult->QWords.qw2 = 0; 356 pResult->QWords.qw3 = pValue->QWords.qw0; 357 } 1364 358 } 1365 359 } 360 } 361 else if (cBits < 128) 362 { 363 if (cBits < 64) 364 { 365 pResult->QWords.qw0 = pValue->QWords.qw0 << cBits; 366 pResult->QWords.qw1 = pValue->QWords.qw0 >> (64 - cBits); 367 pResult->QWords.qw1 |= pValue->QWords.qw1 << cBits; 368 pResult->QWords.qw2 = pValue->QWords.qw1 >> (64 - cBits); 369 pResult->QWords.qw2 |= pValue->QWords.qw2 << cBits; 370 pResult->QWords.qw3 = pValue->QWords.qw2 >> (64 - cBits); 371 pResult->QWords.qw3 |= pValue->QWords.qw3 << cBits; 372 } 1366 373 else 1367 NormDivisor = *pValue2;1368 1369 RTUInt128SetZero(pQuotient);1370 *pRemainder = *pValue1;1371 1372 /*1373 * Do the division.1374 */1375 if (RTUInt128IsLargerOrEqual(pRemainder, pValue2))1376 374 { 1377 for (;;) 375 cBits -= 64; 376 pResult->QWords.qw0 = 0; 377 pResult->QWords.qw1 = pValue->QWords.qw0 << cBits; 378 pResult->QWords.qw2 = pValue->QWords.qw0 >> (64 - cBits); 379 pResult->QWords.qw2 |= pValue->QWords.qw1 << cBits; 380 pResult->QWords.qw3 = pValue->QWords.qw1 >> (64 - cBits); 381 pResult->QWords.qw3 |= pValue->QWords.qw2 << cBits; 382 } 383 } 384 else 385 { 386 if (cBits < 192) 387 { 388 cBits -= 128; 389 pResult->QWords.qw0 = 0; 390 pResult->QWords.qw1 = 0; 391 pResult->QWords.qw2 = pValue->QWords.qw0 << cBits; 392 pResult->QWords.qw3 = pValue->QWords.qw0 >> (64 - cBits); 393 pResult->QWords.qw3 |= pValue->QWords.qw1 << cBits; 394 } 395 else 396 { 397 cBits -= 192; 398 pResult->QWords.qw0 = 0; 399 pResult->QWords.qw1 = 0; 400 pResult->QWords.qw2 = 0; 401 pResult->QWords.qw3 = pValue->QWords.qw0 << cBits; 402 } 403 } 404 return pResult; 405 } 406 407 408 /** 409 * Shifts a 256-bit unsigned integer value @a cBits to the right. 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. This is masked 415 * by 255 before shifting. 416 */ 417 DECLINLINE(PRTUINT256U) RTUInt256ShiftRight(PRTUINT256U pResult, PCRTUINT256U pValue, unsigned cBits) 418 { 419 /* This is a bit bulky & impractical since we cannot access the data using 420 an array because it is organized according to host endianness. Sigh. */ 421 cBits &= 255; 422 if (!(cBits & 0x3f)) 423 { 424 if (cBits == 0) 425 *pResult = *pValue; 426 else 427 { 428 if (cBits == 64) 1378 429 { 1379 if (RTUInt128IsLargerOrEqual(pRemainder, &NormDivisor)) 430 pResult->QWords.qw0 = pValue->QWords.qw1; 431 pResult->QWords.qw1 = pValue->QWords.qw2; 432 pResult->QWords.qw2 = pValue->QWords.qw3; 433 } 434 else 435 { 436 if (cBits == 128) 1380 437 { 1381 RTUInt128AssignSub(pRemainder, &NormDivisor);1382 RTUInt128AssignOrBit(pQuotient, iBitAdder);438 pResult->QWords.qw0 = pValue->QWords.qw2; 439 pResult->QWords.qw1 = pValue->QWords.qw3; 1383 440 } 1384 if (RTUInt128IsSmaller(pRemainder, pValue2)) 1385 break; 1386 RTUInt128AssignShiftRight(&NormDivisor, 1); 1387 iBitAdder--; 441 else 442 { 443 pResult->QWords.qw0 = pValue->QWords.qw3; 444 pResult->QWords.qw1 = 0; 445 } 446 pResult->QWords.qw2 = 0; 1388 447 } 448 pResult->QWords.qw3 = 0; 1389 449 } 1390 450 } 1391 return pQuotient; 451 else if (cBits < 128) 452 { 453 if (cBits < 64) 454 { 455 pResult->QWords.qw0 = pValue->QWords.qw0 >> cBits; 456 pResult->QWords.qw0 |= pValue->QWords.qw1 << (64 - cBits); 457 pResult->QWords.qw1 = pValue->QWords.qw1 >> cBits; 458 pResult->QWords.qw1 |= pValue->QWords.qw2 << (64 - cBits); 459 pResult->QWords.qw2 = pValue->QWords.qw2 >> cBits; 460 pResult->QWords.qw2 |= pValue->QWords.qw3 << (64 - cBits); 461 pResult->QWords.qw3 = pValue->QWords.qw3 >> cBits; 462 } 463 else 464 { 465 cBits -= 64; 466 pResult->QWords.qw0 = pValue->QWords.qw1 >> cBits; 467 pResult->QWords.qw0 |= pValue->QWords.qw2 << (64 - cBits); 468 pResult->QWords.qw1 = pValue->QWords.qw2 >> cBits; 469 pResult->QWords.qw1 |= pValue->QWords.qw3 << (64 - cBits); 470 pResult->QWords.qw2 = pValue->QWords.qw3 >> cBits; 471 pResult->QWords.qw3 = 0; 472 } 473 } 474 else 475 { 476 if (cBits < 192) 477 { 478 cBits -= 128; 479 pResult->QWords.qw0 = pValue->QWords.qw2 >> cBits; 480 pResult->QWords.qw0 |= pValue->QWords.qw3 << (64 - cBits); 481 pResult->QWords.qw1 = pValue->QWords.qw3 >> cBits; 482 pResult->QWords.qw2 = 0; 483 pResult->QWords.qw3 = 0; 484 } 485 else 486 { 487 cBits -= 192; 488 pResult->QWords.qw0 = pValue->QWords.qw3 >> cBits; 489 pResult->QWords.qw1 = 0; 490 pResult->QWords.qw2 = 0; 491 pResult->QWords.qw3 = 0; 492 } 493 } 494 return pResult; 495 } 496 497 498 /** 499 * Boolean not (result 0 or 1). 500 * 501 * @returns pResult. 502 * @param pResult The result variable. 503 * @param pValue The value. 504 */ 505 DECLINLINE(PRTUINT256U) RTUInt256BooleanNot(PRTUINT256U pResult, PCRTUINT256U pValue) 506 { 507 pResult->QWords.qw0 = RTUInt256IsZero(pValue); 508 pResult->QWords.qw1 = 0; 509 pResult->QWords.qw2 = 0; 510 pResult->QWords.qw3 = 0; 511 return pResult; 512 } 513 514 515 /** 516 * Bitwise not (flips each bit of the 256 bits). 517 * 518 * @returns pResult. 519 * @param pResult The result variable. 520 * @param pValue The value. 521 */ 522 DECLINLINE(PRTUINT256U) RTUInt256BitwiseNot(PRTUINT256U pResult, PCRTUINT256U pValue) 523 { 524 pResult->QWords.qw0 = ~pValue->QWords.qw0; 525 pResult->QWords.qw1 = ~pValue->QWords.qw1; 526 pResult->QWords.qw2 = ~pValue->QWords.qw2; 527 pResult->QWords.qw3 = ~pValue->QWords.qw3; 528 return pResult; 529 } 530 531 532 /** 533 * Assigns one 256-bit unsigned integer value to another. 534 * 535 * @returns pResult 536 * @param pResult The result variable. 537 * @param pValue The value to assign. 538 */ 539 DECLINLINE(PRTUINT256U) RTUInt256Assign(PRTUINT256U pResult, PCRTUINT256U pValue) 540 { 541 pResult->QWords.qw0 = pValue->QWords.qw0; 542 pResult->QWords.qw1 = pValue->QWords.qw1; 543 pResult->QWords.qw2 = pValue->QWords.qw2; 544 pResult->QWords.qw3 = pValue->QWords.qw3; 545 return pResult; 546 } 547 548 549 /** 550 * Assigns a boolean value to 256-bit unsigned integer. 551 * 552 * @returns pValueResult 553 * @param pValueResult The result variable. 554 * @param fValue The boolean value. 555 */ 556 DECLINLINE(PRTUINT256U) RTUInt256AssignBoolean(PRTUINT256U pValueResult, bool fValue) 557 { 558 pValueResult->QWords.qw0 = fValue; 559 pValueResult->QWords.qw1 = 0; 560 pValueResult->QWords.qw2 = 0; 561 pValueResult->QWords.qw3 = 0; 562 return pValueResult; 563 } 564 565 566 /** 567 * Assigns a 8-bit unsigned integer value to 256-bit unsigned integer. 568 * 569 * @returns pValueResult 570 * @param pValueResult The result variable. 571 * @param u8Value The 8-bit unsigned integer value. 572 */ 573 DECLINLINE(PRTUINT256U) RTUInt256AssignU8(PRTUINT256U pValueResult, uint8_t u8Value) 574 { 575 pValueResult->QWords.qw0 = u8Value; 576 pValueResult->QWords.qw1 = 0; 577 pValueResult->QWords.qw2 = 0; 578 pValueResult->QWords.qw3 = 0; 579 return pValueResult; 580 } 581 582 583 /** 584 * Assigns a 16-bit unsigned integer value to 256-bit unsigned integer. 585 * 586 * @returns pValueResult 587 * @param pValueResult The result variable. 588 * @param u16Value The 16-bit unsigned integer value. 589 */ 590 DECLINLINE(PRTUINT256U) RTUInt256AssignU16(PRTUINT256U pValueResult, uint16_t u16Value) 591 { 592 pValueResult->QWords.qw0 = u16Value; 593 pValueResult->QWords.qw1 = 0; 594 pValueResult->QWords.qw2 = 0; 595 pValueResult->QWords.qw3 = 0; 596 return pValueResult; 597 } 598 599 600 /** 601 * Assigns a 32-bit unsigned integer value to 256-bit unsigned integer. 602 * 603 * @returns pValueResult 604 * @param pValueResult The result variable. 605 * @param u32Value The 32-bit unsigned integer value. 606 */ 607 DECLINLINE(PRTUINT256U) RTUInt256AssignU32(PRTUINT256U pValueResult, uint32_t u32Value) 608 { 609 pValueResult->QWords.qw0 = u32Value; 610 pValueResult->QWords.qw1 = 0; 611 pValueResult->QWords.qw2 = 0; 612 pValueResult->QWords.qw3 = 0; 613 return pValueResult; 614 } 615 616 617 /** 618 * Assigns a 64-bit unsigned integer value to 256-bit unsigned integer. 619 * 620 * @returns pValueResult 621 * @param pValueResult The result variable. 622 * @param u64Value The 64-bit unsigned integer value. 623 */ 624 DECLINLINE(PRTUINT256U) RTUInt256AssignU64(PRTUINT256U pValueResult, uint64_t u64Value) 625 { 626 pValueResult->QWords.qw0 = u64Value; 627 pValueResult->QWords.qw1 = 0; 628 pValueResult->QWords.qw2 = 0; 629 pValueResult->QWords.qw3 = 0; 630 return pValueResult; 631 } 632 633 634 /** 635 * Adds two 256-bit unsigned integer values, storing the result in the first. 636 * 637 * @returns pValue1Result. 638 * @param pValue1Result The first value and result. 639 * @param pValue2 The second value. 640 */ 641 DECLINLINE(PRTUINT256U) RTUInt256AssignAdd(PRTUINT256U pValue1Result, PCRTUINT256U pValue2) 642 { 643 RTUINT256U const uTmpValue1 = *pValue1Result; /* lazy bird */ 644 return RTUInt256Add(pValue1Result, &uTmpValue1, pValue2); 645 } 646 647 648 /** 649 * Adds a 64-bit unsigned integer value to a 256-bit unsigned integer values, 650 * storing the result in the 256-bit one. 651 * 652 * @returns pValue1Result. 653 * @param pValue1Result The first value and result. 654 * @param uValue2 The second value, 64-bit. 655 */ 656 DECLINLINE(PRTUINT256U) RTUInt256AssignAddU64(PRTUINT256U pValue1Result, uint64_t uValue2) 657 { 658 RTUINT256U const uTmpValue1 = *pValue1Result; /* lazy bird */ 659 return RTUInt256AddU64(pValue1Result, &uTmpValue1, uValue2); 660 } 661 662 663 /** 664 * Subtracts two 256-bit unsigned integer values, storing the result in the 665 * first. 666 * 667 * @returns pValue1Result. 668 * @param pValue1Result The minuend value and result. 669 * @param pValue2 The subtrahend value. 670 */ 671 DECLINLINE(PRTUINT256U) RTUInt256AssignSub(PRTUINT256U pValue1Result, PCRTUINT256U pValue2) 672 { 673 RTUINT256U const uTmpValue1 = *pValue1Result; /* lazy bird */ 674 return RTUInt256Sub(pValue1Result, &uTmpValue1, pValue2); 675 } 676 677 678 #if 0 679 /** 680 * Negates a 256 number, storing the result in the input. 681 * 682 * @returns pValueResult. 683 * @param pValueResult The value to negate. 684 */ 685 DECLINLINE(PRTUINT256U) RTUInt256AssignNeg(PRTUINT256U pValueResult) 686 { 687 /* result = 0 - value */ 688 if (pValueResult->s.Lo != 0) 689 { 690 pValueResult->s.Lo = UINT64_C(0) - pValueResult->s.Lo; 691 pValueResult->s.Hi = UINT64_MAX - pValueResult->s.Hi; 692 } 693 else 694 pValueResult->s.Hi = UINT64_C(0) - pValueResult->s.Hi; 695 return pValueResult; 696 } 697 #endif 698 699 700 /** 701 * Multiplies two 256-bit unsigned integer values, storing the result in the 702 * first. 703 * 704 * @returns pValue1Result. 705 * @param pValue1Result The first value and result. 706 * @param pValue2 The second value. 707 */ 708 DECLINLINE(PRTUINT256U) RTUInt256AssignMul(PRTUINT256U pValue1Result, PCRTUINT256U pValue2) 709 { 710 RTUINT256U Result; 711 RTUInt256Mul(&Result, pValue1Result, pValue2); 712 *pValue1Result = Result; 713 return pValue1Result; 714 } 715 716 717 /** 718 * Divides a 256-bit unsigned integer value by another, storing the result in 719 * the first. 720 * 721 * @returns pValue1Result. 722 * @param pValue1Result The dividend value and result. 723 * @param pValue2 The divisor value. 724 */ 725 DECLINLINE(PRTUINT256U) RTUInt256AssignDiv(PRTUINT256U pValue1Result, PCRTUINT256U pValue2) 726 { 727 RTUINT256U Result; 728 RTUINT256U Ignored; 729 RTUInt256DivRem(&Result, &Ignored, pValue1Result, pValue2); 730 *pValue1Result = Result; 731 return pValue1Result; 732 } 733 734 735 /** 736 * Divides a 256-bit unsigned integer value by another, storing the remainder in 737 * the first. 738 * 739 * @returns pValue1Result. 740 * @param pValue1Result The dividend value and result (remainder). 741 * @param pValue2 The divisor value. 742 */ 743 DECLINLINE(PRTUINT256U) RTUInt256AssignMod(PRTUINT256U pValue1Result, PCRTUINT256U pValue2) 744 { 745 RTUINT256U Ignored; 746 RTUINT256U Result; 747 RTUInt256DivRem(&Ignored, &Result, pValue1Result, pValue2); 748 *pValue1Result = Result; 749 return pValue1Result; 750 } 751 752 753 /** 754 * Performs a bitwise AND of two 256-bit unsigned integer values and assigned 755 * the result to the first one. 756 * 757 * @returns pValue1Result. 758 * @param pValue1Result The first value and result. 759 * @param pValue2 The second value. 760 */ 761 DECLINLINE(PRTUINT256U) RTUInt256AssignAnd(PRTUINT256U pValue1Result, PCRTUINT256U pValue2) 762 { 763 pValue1Result->QWords.qw0 &= pValue2->QWords.qw0; 764 pValue1Result->QWords.qw1 &= pValue2->QWords.qw1; 765 pValue1Result->QWords.qw2 &= pValue2->QWords.qw2; 766 pValue1Result->QWords.qw3 &= pValue2->QWords.qw3; 767 return pValue1Result; 768 } 769 770 771 #if 0 772 /** 773 * Performs a bitwise AND of a 256-bit unsigned integer value and a mask made 774 * up of the first N bits, assigning the result to the the 256-bit value. 775 * 776 * @returns pValueResult. 777 * @param pValueResult The value and result. 778 * @param cBits The number of bits to AND (counting from the first 779 * bit). 780 */ 781 DECLINLINE(PRTUINT256U) RTUInt256AssignAndNFirstBits(PRTUINT256U pValueResult, unsigned cBits) 782 { 783 if (cBits <= 64) 784 { 785 if (cBits != 64) 786 pValueResult->s.Lo &= (RT_BIT_64(cBits) - 1); 787 pValueResult->s.Hi = 0; 788 } 789 else if (cBits < 256) 790 pValueResult->s.Hi &= (RT_BIT_64(cBits - 64) - 1); 791 /** @todo \#if ARCH_BITS >= 64 */ 792 return pValueResult; 793 } 794 #endif 795 796 797 /** 798 * Performs a bitwise OR of two 256-bit unsigned integer values and assigned 799 * the result to the first one. 800 * 801 * @returns pValue1Result. 802 * @param pValue1Result The first value and result. 803 * @param pValue2 The second value. 804 */ 805 DECLINLINE(PRTUINT256U) RTUInt256AssignOr(PRTUINT256U pValue1Result, PCRTUINT256U pValue2) 806 { 807 pValue1Result->QWords.qw0 |= pValue2->QWords.qw0; 808 pValue1Result->QWords.qw1 |= pValue2->QWords.qw1; 809 pValue1Result->QWords.qw2 |= pValue2->QWords.qw2; 810 pValue1Result->QWords.qw3 |= pValue2->QWords.qw3; 811 return pValue1Result; 812 } 813 814 815 DECLINLINE(PRTUINT256U) RTUInt256BitSet(PRTUINT256U pValueResult, unsigned iBit); 816 817 /** 818 * ORs in a bit and assign the result to the input value. 819 * 820 * @returns pValue1Result. 821 * @param pValue1Result The first value and result. 822 * @param iBit The bit to set (0 based). 823 */ 824 DECLINLINE(PRTUINT256U) RTUInt256AssignOrBit(PRTUINT256U pValue1Result, uint32_t iBit) 825 { 826 return RTUInt256BitSet(pValue1Result, (unsigned)iBit); 827 } 828 829 830 /** 831 * Performs a bitwise XOR of two 256-bit unsigned integer values and assigned 832 * the result to the first one. 833 * 834 * @returns pValue1Result. 835 * @param pValue1Result The first value and result. 836 * @param pValue2 The second value. 837 */ 838 DECLINLINE(PRTUINT256U) RTUInt256AssignXor(PRTUINT256U pValue1Result, PCRTUINT256U pValue2) 839 { 840 pValue1Result->QWords.qw0 ^= pValue2->QWords.qw0; 841 pValue1Result->QWords.qw1 ^= pValue2->QWords.qw1; 842 pValue1Result->QWords.qw2 ^= pValue2->QWords.qw2; 843 pValue1Result->QWords.qw3 ^= pValue2->QWords.qw3; 844 return pValue1Result; 845 } 846 847 848 /** 849 * Performs a bitwise left shift on a 256-bit unsigned integer value, assigning 850 * the result to it. 851 * 852 * @returns pValueResult. 853 * @param pValueResult The first value and result. 854 * @param cBits The number of bits to shift - signed. Negative 855 * values are translated to right shifts. If the 856 * absolute value is 256 or higher, the value is set to 857 * zero. 858 * 859 * @note This works differently from RTUInt256ShiftLeft and 860 * RTUInt256ShiftRight in that the shift count is signed and not masked 861 * by 255. 862 */ 863 DECLINLINE(PRTUINT256U) RTUInt256AssignShiftLeft(PRTUINT256U pValueResult, int cBits) 864 { 865 if (cBits == 0) 866 return pValueResult; 867 if (cBits > 0) 868 { 869 /* (left shift) */ 870 if (cBits < 256) 871 { 872 RTUINT256U const InVal = *pValueResult; 873 return RTUInt256ShiftLeft(pValueResult, &InVal, cBits); 874 } 875 } 876 else if (cBits > -256) 877 { 878 /* (right shift) */ 879 cBits = -cBits; 880 RTUINT256U const InVal = *pValueResult; 881 return RTUInt256ShiftRight(pValueResult, &InVal, cBits); 882 } 883 return RTUInt256SetZero(pValueResult); 884 } 885 886 887 /** 888 * Performs a bitwise left shift on a 256-bit unsigned integer value, assigning 889 * the result to it. 890 * 891 * @returns pValueResult. 892 * @param pValueResult The first value and result. 893 * @param cBits The number of bits to shift - signed. Negative 894 * values are translated to left shifts. If the 895 * absolute value is 256 or higher, the value is set to 896 * zero. 897 * 898 * @note This works differently from RTUInt256ShiftRight and 899 * RTUInt256ShiftLeft in that the shift count is signed and not masked 900 * by 255. 901 */ 902 DECLINLINE(PRTUINT256U) RTUInt256AssignShiftRight(PRTUINT256U pValueResult, int cBits) 903 { 904 if (cBits == 0) 905 return pValueResult; 906 if (cBits > 0) 907 { 908 /* (right shift) */ 909 if (cBits < 256) 910 { 911 RTUINT256U const InVal = *pValueResult; 912 return RTUInt256ShiftRight(pValueResult, &InVal, cBits); 913 } 914 } 915 else if (cBits > -256) 916 { 917 /* (left shift) */ 918 cBits = -cBits; 919 RTUINT256U const InVal = *pValueResult; 920 return RTUInt256ShiftLeft(pValueResult, &InVal, cBits); 921 } 922 return RTUInt256SetZero(pValueResult); 923 } 924 925 926 /** 927 * Performs a bitwise NOT on a 256-bit unsigned integer value, assigning the 928 * result to it. 929 * 930 * @returns pValueResult 931 * @param pValueResult The value and result. 932 */ 933 DECLINLINE(PRTUINT256U) RTUInt256AssignBitwiseNot(PRTUINT256U pValueResult) 934 { 935 pValueResult->QWords.qw0 = ~pValueResult->QWords.qw0; 936 pValueResult->QWords.qw1 = ~pValueResult->QWords.qw1; 937 pValueResult->QWords.qw2 = ~pValueResult->QWords.qw2; 938 pValueResult->QWords.qw3 = ~pValueResult->QWords.qw3; 939 return pValueResult; 940 } 941 942 943 /** 944 * Performs a boolean NOT on a 256-bit unsigned integer value, assigning the 945 * result to it. 946 * 947 * @returns pValueResult 948 * @param pValueResult The value and result. 949 */ 950 DECLINLINE(PRTUINT256U) RTUInt256AssignBooleanNot(PRTUINT256U pValueResult) 951 { 952 return RTUInt256AssignBoolean(pValueResult, RTUInt256IsZero(pValueResult)); 953 } 954 955 956 /** 957 * Compares two 256-bit unsigned integer values. 958 * 959 * @retval 0 if equal. 960 * @retval -1 if the first value is smaller than the second. 961 * @retval 1 if the first value is larger than the second. 962 * 963 * @param pValue1 The first value. 964 * @param pValue2 The second value. 965 */ 966 DECLINLINE(int) RTUInt256Compare(PCRTUINT256U pValue1, PCRTUINT256U pValue2) 967 { 968 if (pValue1->QWords.qw3 != pValue2->QWords.qw3) 969 return pValue1->QWords.qw3 > pValue2->QWords.qw3 ? 1 : -1; 970 if (pValue1->QWords.qw2 != pValue2->QWords.qw2) 971 return pValue1->QWords.qw2 > pValue2->QWords.qw2 ? 1 : -1; 972 if (pValue1->QWords.qw1 != pValue2->QWords.qw1) 973 return pValue1->QWords.qw1 > pValue2->QWords.qw1 ? 1 : -1; 974 if (pValue1->QWords.qw0 != pValue2->QWords.qw0) 975 return pValue1->QWords.qw3 > pValue2->QWords.qw3 ? 1 : -1; 976 return 0; 977 } 978 979 980 /** 981 * Tests if a 256-bit unsigned integer value is smaller than another. 982 * 983 * @returns true if the first value is smaller, false if not. 984 * @param pValue1 The first value. 985 * @param pValue2 The second value. 986 */ 987 DECLINLINE(bool) RTUInt256IsSmaller(PCRTUINT256U pValue1, PCRTUINT256U pValue2) 988 { 989 return pValue1->QWords.qw3 < pValue2->QWords.qw3 990 || ( pValue1->QWords.qw3 == pValue2->QWords.qw3 991 && ( pValue1->QWords.qw2 < pValue2->QWords.qw2 992 || ( pValue1->QWords.qw2 == pValue2->QWords.qw2 993 && ( pValue1->QWords.qw1 < pValue2->QWords.qw1 994 || ( pValue1->QWords.qw1 == pValue2->QWords.qw1 995 && pValue1->QWords.qw0 < pValue2->QWords.qw0))))); 996 } 997 998 999 /** 1000 * Tests if a 256-bit unsigned integer value is larger than another. 1001 * 1002 * @returns true if the first value is larger, false if not. 1003 * @param pValue1 The first value. 1004 * @param pValue2 The second value. 1005 */ 1006 DECLINLINE(bool) RTUInt256IsLarger(PCRTUINT256U pValue1, PCRTUINT256U pValue2) 1007 { 1008 return pValue1->QWords.qw3 > pValue2->QWords.qw3 1009 || ( pValue1->QWords.qw3 == pValue2->QWords.qw3 1010 && ( pValue1->QWords.qw2 > pValue2->QWords.qw2 1011 || ( pValue1->QWords.qw2 == pValue2->QWords.qw2 1012 && ( pValue1->QWords.qw1 > pValue2->QWords.qw1 1013 || ( pValue1->QWords.qw1 == pValue2->QWords.qw1 1014 && pValue1->QWords.qw0 > pValue2->QWords.qw0))))); 1015 } 1016 1017 1018 /** 1019 * Tests if a 256-bit unsigned integer value is larger or equal than another. 1020 * 1021 * @returns true if the first value is larger or equal, false if not. 1022 * @param pValue1 The first value. 1023 * @param pValue2 The second value. 1024 */ 1025 DECLINLINE(bool) RTUInt256IsLargerOrEqual(PCRTUINT256U pValue1, PCRTUINT256U pValue2) 1026 { 1027 return pValue1->QWords.qw3 > pValue2->QWords.qw3 1028 || ( pValue1->QWords.qw3 == pValue2->QWords.qw3 1029 && ( pValue1->QWords.qw2 > pValue2->QWords.qw2 1030 || ( pValue1->QWords.qw2 == pValue2->QWords.qw2 1031 && ( pValue1->QWords.qw1 > pValue2->QWords.qw1 1032 || ( pValue1->QWords.qw1 == pValue2->QWords.qw1 1033 && pValue1->QWords.qw0 >= pValue2->DWords.dw0))))); 1034 } 1035 1036 1037 /** 1038 * Tests if two 256-bit unsigned integer values not equal. 1039 * 1040 * @returns true if equal, false if not equal. 1041 * @param pValue1 The first value. 1042 * @param pValue2 The second value. 1043 */ 1044 DECLINLINE(bool) RTUInt256IsEqual(PCRTUINT256U pValue1, PCRTUINT256U pValue2) 1045 { 1046 return pValue1->QWords.qw0 == pValue2->QWords.qw0 1047 && pValue1->QWords.qw1 == pValue2->QWords.qw1 1048 && pValue1->QWords.qw2 == pValue2->QWords.qw2 1049 && pValue1->QWords.qw3 == pValue2->QWords.qw3; 1050 } 1051 1052 1053 /** 1054 * Tests if two 256-bit unsigned integer values are not equal. 1055 * 1056 * @returns true if not equal, false if equal. 1057 * @param pValue1 The first value. 1058 * @param pValue2 The second value. 1059 */ 1060 DECLINLINE(bool) RTUInt256IsNotEqual(PCRTUINT256U pValue1, PCRTUINT256U pValue2) 1061 { 1062 return !RTUInt256IsEqual(pValue1, pValue2); 1063 } 1064 1065 1066 /** 1067 * Sets a bit in a 256-bit unsigned integer type. 1068 * 1069 * @returns pValueResult. 1070 * @param pValueResult The input and output value. 1071 * @param iBit The bit to set. 1072 */ 1073 DECLINLINE(PRTUINT256U) RTUInt256BitSet(PRTUINT256U pValueResult, unsigned iBit) 1074 { 1075 if (iBit < 256) 1076 { 1077 unsigned idxQWord = iBit >> 6; 1078 #ifdef RT_BIG_ENDIAN 1079 idxQWord = RT_ELEMENTS(pValueResult->au64) - idxQWord; 1080 #endif 1081 iBit &= 0x3f; 1082 pValueResult->au64[idxQWord] |= RT_BIT_64(iBit); 1083 } 1084 return pValueResult; 1085 } 1086 1087 1088 /** 1089 * Sets a bit in a 256-bit unsigned integer type. 1090 * 1091 * @returns pValueResult. 1092 * @param pValueResult The input and output value. 1093 * @param iBit The bit to set. 1094 */ 1095 DECLINLINE(PRTUINT256U) RTUInt256BitClear(PRTUINT256U pValueResult, unsigned iBit) 1096 { 1097 if (iBit < 256) 1098 { 1099 unsigned idxQWord = iBit >> 6; 1100 #ifdef RT_BIG_ENDIAN 1101 idxQWord = RT_ELEMENTS(pValueResult->au64) - idxQWord; 1102 #endif 1103 iBit &= 0x3f; 1104 pValueResult->au64[idxQWord] &= ~RT_BIT_64(iBit); 1105 } 1106 return pValueResult; 1107 } 1108 1109 1110 /** 1111 * Tests if a bit in a 256-bit unsigned integer value is set. 1112 * 1113 * @returns pValueResult. 1114 * @param pValueResult The input and output value. 1115 * @param iBit The bit to test. 1116 */ 1117 DECLINLINE(bool) RTUInt256BitTest(PRTUINT256U pValueResult, unsigned iBit) 1118 { 1119 bool fRc; 1120 if (iBit < 256) 1121 { 1122 unsigned idxQWord = iBit >> 6; 1123 #ifdef RT_BIG_ENDIAN 1124 idxQWord = RT_ELEMENTS(pValueResult->au64) - idxQWord; 1125 #endif 1126 iBit &= 0x3f; 1127 fRc = RT_BOOL(pValueResult->au64[idxQWord] & RT_BIT_64(iBit)); 1128 } 1129 else 1130 fRc = false; 1131 return fRc; 1132 } 1133 1134 1135 /** 1136 * Set a range of bits a 256-bit unsigned integer value. 1137 * 1138 * @returns pValueResult. 1139 * @param pValueResult The input and output value. 1140 * @param iFirstBit The first bit to test. 1141 * @param cBits The number of bits to set. 1142 */ 1143 DECLINLINE(PRTUINT256U) RTUInt256BitSetRange(PRTUINT256U pValueResult, unsigned iFirstBit, unsigned cBits) 1144 { 1145 /* bounds check & fix. */ 1146 if (iFirstBit < 256) 1147 { 1148 if (iFirstBit + cBits > 256) 1149 cBits = 256 - iFirstBit; 1150 1151 /* Work the au64 array: */ 1152 #ifdef RT_BIG_ENDIAN 1153 int idxQWord = RT_ELEMENTS(pValueResult->au64) - (iFirstBit >> 6); 1154 int const idxInc = -1; 1155 #else 1156 int idxQWord = iFirstBit >> 6; 1157 int const idxInc = 1; 1158 #endif 1159 while (cBits > 0) 1160 { 1161 unsigned iQWordFirstBit = iFirstBit & 0x3f; 1162 unsigned cQWordBits = cBits + iQWordFirstBit >= 64 ? 64 - iQWordFirstBit : cBits; 1163 pValueResult->au64[idxQWord] |= cQWordBits < 64 ? (RT_BIT_64(cQWordBits) - 1) << iQWordFirstBit : UINT64_MAX; 1164 1165 idxQWord += idxInc; 1166 iFirstBit += cQWordBits; 1167 cBits -= cQWordBits; 1168 } 1169 } 1170 return pValueResult; 1171 } 1172 1173 1174 /** 1175 * Test if all the bits of a 256-bit unsigned integer value are set. 1176 * 1177 * @returns true if they are, false if they aren't. 1178 * @param pValue The input and output value. 1179 */ 1180 DECLINLINE(bool) RTUInt256BitAreAllSet(PRTUINT256U pValue) 1181 { 1182 return pValue->QWords.qw0 == UINT64_MAX 1183 && pValue->QWords.qw1 == UINT64_MAX 1184 && pValue->QWords.qw2 == UINT64_MAX 1185 && pValue->QWords.qw3 == UINT64_MAX; 1186 } 1187 1188 1189 /** 1190 * Test if all the bits of a 256-bit unsigned integer value are clear. 1191 * 1192 * @returns true if they are, false if they aren't. 1193 * @param pValue The input and output value. 1194 */ 1195 DECLINLINE(bool) RTUInt256BitAreAllClear(PRTUINT256U pValue) 1196 { 1197 return RTUInt256IsZero(pValue); 1198 } 1199 1200 1201 /** 1202 * Number of significant bits in the value. 1203 * 1204 * This is the same a ASMBitLastSetU64 and ASMBitLastSetU32. 1205 * 1206 * @returns 0 if zero, 1-base index of the last bit set. 1207 * @param pValue The value to examine. 1208 */ 1209 DECLINLINE(uint32_t) RTUInt256BitCount(PCRTUINT256U pValue) 1210 { 1211 uint64_t u64; 1212 uint32_t cBits; 1213 if ((u64 = pValue->QWords.qw3) != 0) 1214 cBits = 192; 1215 else if ((u64 = pValue->QWords.qw2) != 0) 1216 cBits = 128; 1217 else if ((u64 = pValue->QWords.qw1) != 0) 1218 cBits = 64; 1219 else 1220 { 1221 u64 = pValue->QWords.qw0; 1222 cBits = 0; 1223 } 1224 return cBits + ASMBitLastSetU64(u64); 1392 1225 } 1393 1226 … … 1397 1230 RT_C_DECLS_END 1398 1231 1399 #endif /* !IPRT_INCLUDED_uint 128_h */1400 1232 #endif /* !IPRT_INCLUDED_uint256_h */ 1233 -
trunk/src/VBox/Runtime/Makefile.kmk
r94471 r94511 907 907 common/math/bignum-amd64-x86.asm \ 908 908 common/math/RTUInt128MulByU64.asm \ 909 common/math/RTUInt128MulByU64Ex.asm \ 909 910 common/string/RTStrEnd.asm 910 911 … … 3091 3092 common/math/bignum-amd64-x86.asm \ 3092 3093 common/math/RTUInt128MulByU64.asm \ 3094 common/math/RTUInt128MulByU64Ex.asm \ 3093 3095 common/string/RTStrEnd.asm 3094 3096 RuntimeR0Drv_SOURCES.x86 = \ -
trunk/src/VBox/Runtime/common/math/RTUInt128MulByU64Ex.asm
r94493 r94511 34 34 35 35 ;; 36 ; Multiplies a 128-bit number with a 64-bit one .36 ; Multiplies a 128-bit number with a 64-bit one, returning a 256-bit result. 37 37 ; 38 38 ; @returns puResult. … … 41 41 ; @param uValue2 x86:[ebp + 16] gcc:rdx msc:r8 42 42 ; 43 RT_BEGINPROC RTUInt128MulByU64 43 RT_BEGINPROC RTUInt128MulByU64Ex 44 44 ; SEH64_SET_FRAME_xSP 0 45 45 SEH64_END_PROLOGUE … … 61 61 mov rax, [puValue1] 62 62 mul uValue2 63 mov [puResult], rax 64 mov r11, rdx ; S tore the lower half of the result.63 mov [puResult], rax ; Store the 1st 64-bit part of the result. 64 mov r11, rdx ; Save the upper 64 bits for later. 65 65 66 66 ; puValue1->s.Hi * uValue2 … … 68 68 mul uValue2 69 69 add r11, rax ; Calc the second half of the result. 70 mov [puResult + 8], r11 ; Store the high half of the result. 70 adc rdx, 0 71 mov [puResult + 8], r11 ; Store the 2nd 64-bit part of the result. 72 mov [puResult + 16], rdx ; Store the 3rd 64-bit part of the result. 73 xor r10, r10 74 mov [puResult + 24], r10 ; Store the 4th 64-bit part of the result. 71 75 72 76 mov rax, puResult … … 78 82 79 83 ret 80 ENDPROC RTUInt128MulByU64 84 ENDPROC RTUInt128MulByU64Ex 81 85 -
trunk/src/VBox/Runtime/common/string/strformatfloat.cpp
r94336 r94511 177 177 *pszTmp++ = '1'; 178 178 *pszTmp++ = 'm'; 179 pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + RTFLOAT64U_FRACTION_BITS/ 4, 0,179 pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + (RTFLOAT64U_FRACTION_BITS + 3) / 4, 0, 180 180 RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT); 181 181 … … 191 191 *pszTmp++ = '0'; 192 192 *pszTmp++ = 'm'; 193 pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + RTFLOAT64U_FRACTION_BITS/ 4, 0,193 pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + (RTFLOAT64U_FRACTION_BITS + 3) / 4, 0, 194 194 RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT); 195 195 if (fFlags & RTSTR_F_SPECIAL) … … 224 224 */ 225 225 static ssize_t rtStrFormatR80Worker(char *pszBuf, size_t cbBuf, bool const fSign, bool const fInteger, 226 uint64_t const uFraction, uint16_t constuExponent, uint32_t fFlags)226 uint64_t const uFraction, uint16_t uExponent, uint32_t fFlags) 227 227 { 228 228 char szTmp[160]; … … 250 250 : rtStrFormatCopyOutStr(pszBuf, cbBuf, RT_STR_TUPLE("+0")); 251 251 fDenormal = true; 252 if (fInteger) 253 uExponent = 1; 252 254 } 253 255 else if (uExponent == RTFLOAT80U_EXP_MAX) … … 296 298 *pszTmp++ = fInteger ? '1' : '0'; 297 299 *pszTmp++ = 'm'; 298 pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + RTFLOAT80U_FRACTION_BITS/ 4, 0,300 pszTmp += RTStrFormatNumber(pszTmp, uFraction, 16, 2 + (RTFLOAT80U_FRACTION_BITS + 3) / 4, 0, 299 301 RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT); 300 302 -
trunk/src/VBox/Runtime/testcase/tstRTBigNum.cpp
r93115 r94511 30 30 *********************************************************************************************************************************/ 31 31 #include <iprt/bignum.h> 32 #include <iprt/uint256.h> 32 33 #include <iprt/uint128.h> 33 34 #include <iprt/uint64.h> … … 1502 1503 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTests[i].uResult)); 1503 1504 } 1505 1506 /* extended versions */ 1507 RTTestSub(g_hTest, "RTUInt128MulEx"); 1508 static struct 1509 { 1510 RTUINT128U uFactor1, uFactor2; 1511 RTUINT256U uResult; 1512 } const s_aTestsEx[] = 1513 { 1514 { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(~0, 0), RTUINT256_INIT_C(~1, ~0, 1, 0) }, 1515 { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(~0, ~0), RTUINT256_INIT_C(~0, ~1, 0, 1) }, 1516 { RTUINT128_INIT_C(0, 0), RTUINT128_INIT_C(0, 1), RTUINT256_INIT_C(0, 0, 0, 0) }, 1517 { RTUINT128_INIT_C(0, 1), RTUINT128_INIT_C(0, 1), RTUINT256_INIT_C(0, 0, 0, 1) }, 1518 { RTUINT128_INIT_C(0, 2), RTUINT128_INIT_C(0, 2), RTUINT256_INIT_C(0, 0, 0, 4) }, 1519 { RTUINT128_INIT_C(2, 0), RTUINT128_INIT_C(0, 4), RTUINT256_INIT_C(0, 0, 8, 0) }, 1520 { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(0, 0), RTUINT256_INIT_C(0, 0, 0, 0) }, 1521 { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(0, ~0), RTUINT256_INIT_C(0, ~1, ~0, 1) }, 1522 { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(~0, 0), RTUINT256_INIT_C(~1, ~0, 1, 0) }, 1523 { RTUINT128_INIT_C(~0, ~0), RTUINT128_INIT_C(~0, ~0), RTUINT256_INIT_C(~0, ~1, 0, 1) }, 1524 }; 1525 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTestsEx); i++) 1526 { 1527 RTUINT256U uResult; 1528 PRTUINT256U pResult = RTUInt128MulEx(&uResult, &s_aTestsEx[i].uFactor1, &s_aTestsEx[i].uFactor2); 1529 if (pResult != &uResult) 1530 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult); 1531 else if (!RTUInt256IsEqual(&uResult, &s_aTestsEx[i].uResult)) 1532 RTTestIFailed("test #%i failed: \nExp: %016RX64`%016RX64`%016RX64`%016RX64\nGot: %016RX64`%016RX64`%016RX64`%016RX64", 1533 i, s_aTestsEx[i].uResult.QWords.qw3, s_aTestsEx[i].uResult.QWords.qw2, s_aTestsEx[i].uResult.QWords.qw1, 1534 s_aTestsEx[i].uResult.QWords.qw0, uResult.QWords.qw3, uResult.QWords.qw2, uResult.QWords.qw1, 1535 uResult.QWords.qw0 ); 1536 1537 if (s_aTestsEx[i].uFactor2.s.Hi == 0) 1538 { 1539 RTUInt256AssignBitwiseNot(&uResult); 1540 pResult = RTUInt128MulByU64Ex(&uResult, &s_aTestsEx[i].uFactor1, s_aTestsEx[i].uFactor2.s.Lo); 1541 RTTESTI_CHECK(pResult == &uResult); 1542 RTTESTI_CHECK(RTUInt256IsEqual(&uResult, &s_aTestsEx[i].uResult)); 1543 } 1544 1545 if (s_aTestsEx[i].uFactor1.s.Hi == 0) 1546 { 1547 RTUInt256AssignBitwiseNot(&uResult); 1548 pResult = RTUInt128MulByU64Ex(&uResult, &s_aTestsEx[i].uFactor2, s_aTestsEx[i].uFactor1.s.Lo); 1549 RTTESTI_CHECK(pResult == &uResult); 1550 RTTESTI_CHECK(RTUInt256IsEqual(&uResult, &s_aTestsEx[i].uResult)); 1551 } 1552 1553 #if 0 1554 uResult = s_aTestsEx[i].uFactor1; 1555 pResult = RTUInt128AssignMul(&uResult, &s_aTestsEx[i].uFactor2); 1556 RTTESTI_CHECK(pResult == &uResult); 1557 RTTESTI_CHECK(RTUInt128IsEqual(&uResult, &s_aTestsEx[i].uResult)); 1558 #endif 1559 } 1560 1504 1561 } 1505 1562 … … 1681 1738 RTTestIFailed("%u / %u -> %u rem %u, expected %u rem %u", 1682 1739 uDividend, uDivisor, Quotient.u, Remainder.u, uQuotient, uRemainder); 1740 } 1741 } 1742 1743 1744 static void testUInt256Shift(void) 1745 { 1746 { 1747 RTTestSub(g_hTest, "RTUInt256ShiftLeft"); 1748 static struct 1749 { 1750 RTUINT256U uValue, uResult; 1751 unsigned cShift; 1752 } const s_aTests[] = 1753 { 1754 { RTUINT256_INIT_C(0, 0, 0, 0), RTUINT256_INIT_C(0, 0, 0, 0), 1 }, 1755 { RTUINT256_INIT_C(0, 0, 0, 0), RTUINT256_INIT_C(0, 0, 0, 0), 128 }, 1756 { RTUINT256_INIT_C(0, 0, 0, 0), RTUINT256_INIT_C(0, 0, 0, 0), 127 }, 1757 { RTUINT256_INIT_C(0, 0, 0, 0), RTUINT256_INIT_C(0, 0, 0, 0), 255 }, 1758 { RTUINT256_INIT_C(0, 0, 0, 1), RTUINT256_INIT_C(1, 0, 0, 0), 192 }, 1759 { RTUINT256_INIT_C(0, 0, 0, 1), RTUINT256_INIT_C(0, 1, 0, 0), 128 }, 1760 { RTUINT256_INIT_C(0, 0, 0, 1), RTUINT256_INIT_C(0, 0, 1, 0), 64 }, 1761 { RTUINT256_INIT_C(0, 0, 0, 1), RTUINT256_INIT_C(0, 0, 0, 1), 0}, 1762 { RTUINT256_INIT_C(0, 0, 0, 1), RTUINT256_INIT_C(4, 0, 0, 0), 194 }, 1763 { RTUINT256_INIT_C(0, 0, 0, 1), RTUINT256_INIT_C(0, 0, 0x10, 0), 68}, 1764 { RTUINT256_INIT_C(0, 0, 0, 1), RTUINT256_INIT_C(0, 2, 0, 0), 129}, 1765 { RTUINT256_INIT_C(0, 0, 0, 1), RTUINT256_INIT_C(0, 0, 0, 0x8000000000000000), 63 }, 1766 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1767 RTUINT256_INIT_C(0xfdfcfbfaf9f8f7f6, 0xf5f4f3f2f1f0ff3f, 0x3e3d3c3b3a393837, 0x3635343332313000), 8 }, 1768 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1769 RTUINT256_INIT_C(0x6f5f4f3f2f1f0ff3, 0xf3e3d3c3b3a39383, 0x7363534333231300, 0), 68 }, 1770 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1771 RTUINT256_INIT_C(0x3e3d3c3b3a393837, 0x3635343332313000, 0, 0), 136 }, 1772 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1773 RTUINT256_INIT_C(0x6353433323130000, 0, 0, 0), 204 }, 1774 }; 1775 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++) 1776 { 1777 RTUINT256U uResult; 1778 PRTUINT256U pResult = RTUInt256ShiftLeft(&uResult, &s_aTests[i].uValue, s_aTests[i].cShift); 1779 if (pResult != &uResult) 1780 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult); 1781 else if (RTUInt256IsNotEqual(&uResult, &s_aTests[i].uResult)) 1782 RTTestIFailed("test #%i failed: \nExp: %016RX64`%016RX64'%016RX64`%016RX64\nGot: %016RX64`%016RX64'%016RX64`%016RX64", 1783 i, s_aTests[i].uResult.QWords.qw3, s_aTests[i].uResult.QWords.qw2, s_aTests[i].uResult.QWords.qw1, 1784 s_aTests[i].uResult.QWords.qw0, uResult.QWords.qw3, uResult.QWords.qw2, uResult.QWords.qw1, 1785 uResult.QWords.qw0); 1786 1787 uResult = s_aTests[i].uValue; 1788 pResult = RTUInt256AssignShiftLeft(&uResult, s_aTests[i].cShift); 1789 RTTESTI_CHECK(pResult == &uResult); 1790 RTTESTI_CHECK(RTUInt256IsEqual(&uResult, &s_aTests[i].uResult)); 1791 } 1792 } 1793 { 1794 RTTestSub(g_hTest, "RTUInt256ShiftRight"); 1795 static struct 1796 { 1797 RTUINT256U uValue, uResult; 1798 unsigned cShift; 1799 } const s_aTests[] = 1800 { 1801 { RTUINT256_INIT_C(0, 0, 0, 0), RTUINT256_INIT_C(0, 0, 0, 0), 1 }, 1802 { RTUINT256_INIT_C(0, 0, 0, 0), RTUINT256_INIT_C(0, 0, 0, 0), 128 }, 1803 { RTUINT256_INIT_C(0, 0, 0, 0), RTUINT256_INIT_C(0, 0, 0, 0), 127 }, 1804 { RTUINT256_INIT_C(0, 0, 0, 0), RTUINT256_INIT_C(0, 0, 0, 0), 255 }, 1805 { RTUINT256_INIT_C(1, 0, 0, 1), RTUINT256_INIT_C(0, 0, 0, 1), 192}, 1806 { RTUINT256_INIT_C(1, 0, 0, 1), RTUINT256_INIT_C(0, 0, 1, 0), 128}, 1807 { RTUINT256_INIT_C(1, 0, 0, 1), RTUINT256_INIT_C(0, 1, 0, 0), 64}, 1808 { RTUINT256_INIT_C(1, 0, 0, 1), RTUINT256_INIT_C(1, 0, 0, 1), 0}, 1809 { RTUINT256_INIT_C(1, 0, 0, 1), RTUINT256_INIT_C(0, 0, 0, 4), 190}, 1810 { RTUINT256_INIT_C(1, 0, 0, 1), RTUINT256_INIT_C(0, 0, 1, 0), 128}, 1811 { RTUINT256_INIT_C(1, 0, 0, 1), RTUINT256_INIT_C(0, 8, 0, 0), 61}, 1812 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1813 RTUINT256_INIT_C(0x00fefdfcfbfaf9f8, 0xf7f6f5f4f3f2f1f0, 0xff3f3e3d3c3b3a39, 0x3837363534333231), 8 }, 1814 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1815 RTUINT256_INIT_C(0, 0x0fefdfcfbfaf9f8f, 0x7f6f5f4f3f2f1f0f, 0xf3f3e3d3c3b3a393), 68 }, 1816 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1817 RTUINT256_INIT_C(0, 0, 0x0fefdfcfbfaf9f8f, 0x7f6f5f4f3f2f1f0f), 132 }, 1818 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1819 RTUINT256_INIT_C(0, 0, 0, 0xfefdfcfbfaf9f8f7), 192 }, 1820 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1821 RTUINT256_INIT_C(0, 0, 0, 0x000fefdfcfbfaf9f), 204 }, 1822 { RTUINT256_INIT_C(0xfefdfcfbfaf9f8f7, 0xf6f5f4f3f2f1f0ff, 0x3f3e3d3c3b3a3938, 0x3736353433323130), 1823 RTUINT256_INIT_C(0, 0, 0, 1), 255 }, 1824 }; 1825 for (uint32_t i = 0; i < RT_ELEMENTS(s_aTests); i++) 1826 { 1827 RTUINT256U uResult; 1828 PRTUINT256U pResult = RTUInt256ShiftRight(&uResult, &s_aTests[i].uValue, s_aTests[i].cShift); 1829 if (pResult != &uResult) 1830 RTTestIFailed("test #%i returns %p instead of %p", i, pResult, &uResult); 1831 else if (RTUInt256IsNotEqual(&uResult, &s_aTests[i].uResult)) 1832 RTTestIFailed("test #%i failed: \nExp: %016RX64`%016RX64'%016RX64`%016RX64\nGot: %016RX64`%016RX64'%016RX64`%016RX64", 1833 i, s_aTests[i].uResult.QWords.qw3, s_aTests[i].uResult.QWords.qw2, s_aTests[i].uResult.QWords.qw1, 1834 s_aTests[i].uResult.QWords.qw0, uResult.QWords.qw3, uResult.QWords.qw2, uResult.QWords.qw1, 1835 uResult.QWords.qw0); 1836 1837 uResult = s_aTests[i].uValue; 1838 pResult = RTUInt256AssignShiftRight(&uResult, s_aTests[i].cShift); 1839 RTTESTI_CHECK(pResult == &uResult); 1840 RTTESTI_CHECK(RTUInt256IsEqual(&uResult, &s_aTests[i].uResult)); 1841 } 1683 1842 } 1684 1843 } … … 1748 1907 testUInt64Division(); 1749 1908 1909 /* Test some UInt256 bits given what we do above already. */ 1910 testUInt256Shift(); 1911 1750 1912 /* Test the RTBigInt operations. */ 1751 1913 testCompare();
Note:
See TracChangeset
for help on using the changeset viewer.