Changes imported from Abseil "staging" branch:

- 3f758237a43af1f277990492701d26d1153b4d74 Generalize the construction/destruction tests, to prepare... by Greg Falcon <gfalcon@google.com>
  - 7bea88f74fbac34b0c0b00b8b832a544988b9465 Simplify non intrinsic uint128 multiply. by Alex Strelnikov <strel@google.com>

GitOrigin-RevId: 3f758237a43af1f277990492701d26d1153b4d74
Change-Id: Idd9a2df0b90403f10f56bb66d30b76a8ba9f50e7
This commit is contained in:
Abseil Team 2018-01-18 12:42:26 -08:00 committed by vslashg
parent 5a8de8a37e
commit 52a2458965
2 changed files with 11 additions and 26 deletions

View file

@ -570,25 +570,14 @@ inline uint128& uint128::operator*=(uint128 other) {
static_cast<unsigned __int128>(other);
return *this;
#else // ABSL_HAVE_INTRINSIC128
uint64_t a96 = hi_ >> 32;
uint64_t a64 = hi_ & 0xffffffff;
uint64_t a32 = lo_ >> 32;
uint64_t a00 = lo_ & 0xffffffff;
uint64_t b96 = other.hi_ >> 32;
uint64_t b64 = other.hi_ & 0xffffffff;
uint64_t b32 = other.lo_ >> 32;
uint64_t b00 = other.lo_ & 0xffffffff;
// multiply [a96 .. a00] x [b96 .. b00]
// terms higher than c96 disappear off the high side
// terms c96 and c64 are safe to ignore carry bit
uint64_t c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
uint64_t c64 = a64 * b00 + a32 * b32 + a00 * b64;
this->hi_ = (c96 << 32) + c64;
this->lo_ = 0;
// add terms after this one at a time to capture carry
hi_ = hi_ * other.lo_ + lo_ * other.hi_ + a32 * b32;
lo_ = a00 * b00;
*this += uint128(a32 * b00) << 32;
*this += uint128(a00 * b32) << 32;
*this += a00 * b00;
return *this;
#endif // ABSL_HAVE_INTRINSIC128
}