Corrections, documenting and fixes.
This commit is contained in:
		| @@ -3,31 +3,32 @@ | ||||
|  | ||||
| #pragma intrinsic(_umul128) | ||||
| #endif | ||||
| #include <cstring> | ||||
| #include "common/uint128.h" | ||||
|  | ||||
| namespace Common { | ||||
|  | ||||
| u128 Multiply64Into128(u64 a, u64 b) { | ||||
| #ifdef _MSC_VER | ||||
|     u128 result; | ||||
| #ifdef _MSC_VER | ||||
|     result[0] = _umul128(a, b, &result[1]); | ||||
| #else | ||||
|     unsigned __int128 tmp = a; | ||||
|     tmp *= b; | ||||
|     u128 result; | ||||
|     std::memcpy(&result, &tmp, sizeof(u128)); | ||||
| #endif | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| std::pair<u64, u64> Divide128On64(u128 dividend, u64 divisor) { | ||||
| 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 | ||||
|     u64 first_segment = (dividend[1] % divisor) << 32; | ||||
|     const u64 first_segment = (dividend[1] % divisor) << 32; | ||||
|     accum += (first_segment / divisor) << 32; | ||||
|     u64 second_segment = (first_segment % divisor) << 32; | ||||
|     const u64 second_segment = (first_segment % divisor) << 32; | ||||
|     accum += (second_segment / divisor); | ||||
|     remainder += second_segment % divisor; | ||||
|     if (remainder >= divisor) { | ||||
|   | ||||
| @@ -1,13 +1,14 @@ | ||||
| #include <array> | ||||
| #include <cstdint> | ||||
| #include <cstring> | ||||
|  | ||||
| #include <utility> | ||||
| #include "common/common_types.h" | ||||
|  | ||||
| namespace Common { | ||||
|  | ||||
| // This function multiplies 2 u64 values and produces a u128 value; | ||||
| u128 Multiply64Into128(u64 a, u64 b); | ||||
|  | ||||
| std::pair<u64, u64> Divide128On64(u128 dividend, u64 divisor); | ||||
| // This function divides a u128 by a u32 value and produces two u64 values: | ||||
| // the result of division and the remainder | ||||
| std::pair<u64, u64> Divide128On32(u128 dividend, u32 divisor); | ||||
|  | ||||
| } // namespace Common | ||||
|   | ||||
| @@ -152,7 +152,7 @@ std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const { | ||||
|     config.tpidr_el0 = &cb->tpidr_el0; | ||||
|     config.dczid_el0 = 4; | ||||
|     config.ctr_el0 = 0x8444c004; | ||||
|     config.cntfrq_el0 = Timing::CNTFREQ; // Value from fusee. | ||||
|     config.cntfrq_el0 = Timing::CNTFREQ; | ||||
|  | ||||
|     // Unpredictable instructions | ||||
|     config.define_unpredictable_behaviour = true; | ||||
|   | ||||
| @@ -62,9 +62,8 @@ s64 nsToCycles(u64 ns) { | ||||
| } | ||||
|  | ||||
| u64 CpuCyclesToClockCycles(u64 ticks) { | ||||
|     u128 temporal = Common::Multiply64Into128(ticks, CNTFREQ); | ||||
|     std::pair<u64, u64> result = Common::Divide128On64(temporal, BASE_CLOCK_RATE); | ||||
|     return result.first; | ||||
|     const u128 temporal = Common::Multiply64Into128(ticks, CNTFREQ); | ||||
|     return Common::Divide128On32(temporal, static_cast<u32>(BASE_CLOCK_RATE)).first; | ||||
| } | ||||
|  | ||||
| } // namespace Core::Timing | ||||
|   | ||||
		Reference in New Issue
	
	Block a user