summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-02-15 19:26:41 -0400
committerGravatar FernandoS272019-02-15 22:55:31 -0400
commit3ea48e8ebe25686f2342cd79b32409fcd1bccb28 (patch)
treec9e5c3da2dec7ad2ef371a0d6fcd8c9cc11dc729 /src
parentCorrect CNTPCT to use Clock Cycles instead of Cpu Cycles. (diff)
downloadyuzu-3ea48e8ebe25686f2342cd79b32409fcd1bccb28.tar.gz
yuzu-3ea48e8ebe25686f2342cd79b32409fcd1bccb28.tar.xz
yuzu-3ea48e8ebe25686f2342cd79b32409fcd1bccb28.zip
Implement 128 bits Unsigned Integer Multiplication and Division.
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/uint128.cpp18
-rw-r--r--src/common/uint128.h30
3 files changed, 50 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index bdd885273..b0174b445 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -113,6 +113,8 @@ add_library(common STATIC
113 threadsafe_queue.h 113 threadsafe_queue.h
114 timer.cpp 114 timer.cpp
115 timer.h 115 timer.h
116 uint128.cpp
117 uint128.h
116 vector_math.h 118 vector_math.h
117 web_result.h 119 web_result.h
118) 120)
diff --git a/src/common/uint128.cpp b/src/common/uint128.cpp
new file mode 100644
index 000000000..aea7f03e2
--- /dev/null
+++ b/src/common/uint128.cpp
@@ -0,0 +1,18 @@
1
2namespace Common {
3
4std::pair<u64, u64> udiv128(u128 dividend, u64 divisor) {
5 u64 remainder = dividend[0] % divisor;
6 u64 accum = dividend[0] / divisor;
7 if (dividend[1] == 0)
8 return {accum, remainder};
9 // We ignore dividend[1] / divisor as that overflows
10 u64 first_segment = (dividend[1] % divisor) << 32;
11 accum += (first_segment / divisor) << 32;
12 u64 second_segment = (first_segment % divisor) << 32;
13 accum += (second_segment / divisor);
14 remainder += second_segment % divisor;
15 return {accum, remainder};
16}
17
18} // namespace Common
diff --git a/src/common/uint128.h b/src/common/uint128.h
new file mode 100644
index 000000000..fda313bcc
--- /dev/null
+++ b/src/common/uint128.h
@@ -0,0 +1,30 @@
1#include <array>
2#include <cstdint>
3#include <utility>
4#include <cstring>
5#include "common/common_types.h"
6
7namespace Common {
8
9#ifdef _MSC_VER
10#include <intrin.h>
11
12#pragma intrinsic(_umul128)
13#endif
14
15inline u128 umul128(u64 a, u64 b) {
16#ifdef _MSC_VER
17u128 result;
18result[0] = _umul128(a, b, &result[1]);
19#else
20unsigned __int128 tmp = a;
21tmp *= b;
22u128 result;
23std::memcpy(&result, &tmp, sizeof(u128));
24#endif
25return result;
26}
27
28std::pair<u64, u64> udiv128(u128 dividend, u64 divisor);
29
30} // namespace Common