diff options
author | bunnei <bunneidev@gmail.com> | 2019-03-17 02:58:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-17 02:58:59 +0100 |
commit | 059465d496df3ccf6681e8a1d5aee4be3cc0b7e7 (patch) | |
tree | d4fb745d01e5c351a4c6646fb886c84cab5e5afe /src/common/uint128.cpp | |
parent | Merge pull request #2241 from lioncash/compile-flags (diff) | |
parent | Corrections, documenting and fixes. (diff) | |
download | yuzu-059465d496df3ccf6681e8a1d5aee4be3cc0b7e7.tar yuzu-059465d496df3ccf6681e8a1d5aee4be3cc0b7e7.tar.gz yuzu-059465d496df3ccf6681e8a1d5aee4be3cc0b7e7.tar.bz2 yuzu-059465d496df3ccf6681e8a1d5aee4be3cc0b7e7.tar.lz yuzu-059465d496df3ccf6681e8a1d5aee4be3cc0b7e7.tar.xz yuzu-059465d496df3ccf6681e8a1d5aee4be3cc0b7e7.tar.zst yuzu-059465d496df3ccf6681e8a1d5aee4be3cc0b7e7.zip |
Diffstat (limited to 'src/common/uint128.cpp')
-rw-r--r-- | src/common/uint128.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/common/uint128.cpp b/src/common/uint128.cpp new file mode 100644 index 000000000..2238a52c5 --- /dev/null +++ b/src/common/uint128.cpp @@ -0,0 +1,41 @@ +#ifdef _MSC_VER +#include <intrin.h> + +#pragma intrinsic(_umul128) +#endif +#include <cstring> +#include "common/uint128.h" + +namespace Common { + +u128 Multiply64Into128(u64 a, u64 b) { + u128 result; +#ifdef _MSC_VER + result[0] = _umul128(a, b, &result[1]); +#else + unsigned __int128 tmp = a; + tmp *= b; + std::memcpy(&result, &tmp, sizeof(u128)); +#endif + return result; +} + +std::pair<u64, u64> Divide128On32(u128 dividend, u32 divisor) { + u64 remainder = dividend[0] % divisor; + u64 accum = dividend[0] / divisor; + if (dividend[1] == 0) + return {accum, remainder}; + // We ignore dividend[1] / divisor as that overflows + const u64 first_segment = (dividend[1] % divisor) << 32; + accum += (first_segment / divisor) << 32; + const u64 second_segment = (first_segment % divisor) << 32; + accum += (second_segment / divisor); + remainder += second_segment % divisor; + if (remainder >= divisor) { + accum++; + remainder -= divisor; + } + return {accum, remainder}; +} + +} // namespace Common |