mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Use u128 on Clock Cycles calculation.
This commit is contained in:
		
							parent
							
								
									3ea48e8ebe
								
							
						
					
					
						commit
						ecccfe0337
					
				@ -1,7 +1,25 @@
 | 
				
			|||||||
 | 
					#ifdef _MSC_VER
 | 
				
			||||||
 | 
					#include <intrin.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma intrinsic(_umul128)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#include "common/uint128.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Common {
 | 
					namespace Common {
 | 
				
			||||||
 | 
					u128 Multiply64Into128(u64 a, u64 b) {
 | 
				
			||||||
 | 
					#ifdef _MSC_VER
 | 
				
			||||||
 | 
					    u128 result;
 | 
				
			||||||
 | 
					    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> udiv128(u128 dividend, u64 divisor) {
 | 
					std::pair<u64, u64> Divide128On64(u128 dividend, u64 divisor) {
 | 
				
			||||||
    u64 remainder = dividend[0] % divisor;
 | 
					    u64 remainder = dividend[0] % divisor;
 | 
				
			||||||
    u64 accum = dividend[0] / divisor;
 | 
					    u64 accum = dividend[0] / divisor;
 | 
				
			||||||
    if (dividend[1] == 0)
 | 
					    if (dividend[1] == 0)
 | 
				
			||||||
@ -12,6 +30,10 @@ std::pair<u64, u64> udiv128(u128 dividend, u64 divisor) {
 | 
				
			|||||||
    u64 second_segment = (first_segment % divisor) << 32;
 | 
					    u64 second_segment = (first_segment % divisor) << 32;
 | 
				
			||||||
    accum += (second_segment / divisor);
 | 
					    accum += (second_segment / divisor);
 | 
				
			||||||
    remainder += second_segment % divisor;
 | 
					    remainder += second_segment % divisor;
 | 
				
			||||||
 | 
					    if (remainder >= divisor) {
 | 
				
			||||||
 | 
					        accum++;
 | 
				
			||||||
 | 
					        remainder -= divisor;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return {accum, remainder};
 | 
					    return {accum, remainder};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,30 +1,13 @@
 | 
				
			|||||||
#include <array>
 | 
					#include <array>
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
#include <utility>
 | 
					 | 
				
			||||||
#include <cstring>
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					#include <utility>
 | 
				
			||||||
#include "common/common_types.h"
 | 
					#include "common/common_types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Common {
 | 
					namespace Common {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _MSC_VER
 | 
					u128 Multiply64Into128(u64 a, u64 b);
 | 
				
			||||||
#include <intrin.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma intrinsic(_umul128)
 | 
					std::pair<u64, u64> Divide128On64(u128 dividend, u64 divisor);
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
inline u128 umul128(u64 a, u64 b) {
 | 
					 | 
				
			||||||
#ifdef _MSC_VER
 | 
					 | 
				
			||||||
u128 result;
 | 
					 | 
				
			||||||
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> udiv128(u128 dividend, u64 divisor);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Common
 | 
					} // namespace Common
 | 
				
			||||||
 | 
				
			|||||||
@ -120,7 +120,7 @@ public:
 | 
				
			|||||||
        return std::max(parent.core_timing.GetDowncount(), 0);
 | 
					        return std::max(parent.core_timing.GetDowncount(), 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    u64 GetCNTPCT() override {
 | 
					    u64 GetCNTPCT() override {
 | 
				
			||||||
        return CpuCyclesToClockCycles(parent.core_timing.GetTicks());
 | 
					        return Timing::CpuCyclesToClockCycles(parent.core_timing.GetTicks());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ARM_Dynarmic& parent;
 | 
					    ARM_Dynarmic& parent;
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
#include <cinttypes>
 | 
					#include <cinttypes>
 | 
				
			||||||
#include <limits>
 | 
					#include <limits>
 | 
				
			||||||
#include "common/logging/log.h"
 | 
					#include "common/logging/log.h"
 | 
				
			||||||
 | 
					#include "common/uint128.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Core::Timing {
 | 
					namespace Core::Timing {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -61,10 +62,9 @@ s64 nsToCycles(u64 ns) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u64 CpuCyclesToClockCycles(u64 ticks) {
 | 
					u64 CpuCyclesToClockCycles(u64 ticks) {
 | 
				
			||||||
    u64 result = ticks;
 | 
					    u128 temporal = Common::Multiply64Into128(ticks, CNTFREQ);
 | 
				
			||||||
    result *= CNTFREQ;
 | 
					    std::pair<u64, u64> result = Common::Divide128On64(temporal, BASE_CLOCK_RATE);
 | 
				
			||||||
    result /= BASE_CLOCK_RATE;
 | 
					    return result.first;
 | 
				
			||||||
    return static_cast<u64>(result);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Core::Timing
 | 
					} // namespace Core::Timing
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,7 @@ namespace Core::Timing {
 | 
				
			|||||||
// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz
 | 
					// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz
 | 
				
			||||||
// The exact value used is of course unverified.
 | 
					// The exact value used is of course unverified.
 | 
				
			||||||
constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch clock speed is 1020MHz un/docked
 | 
					constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch clock speed is 1020MHz un/docked
 | 
				
			||||||
constexpr u64 CNTFREQ = 19200000;  // Value from fusee.
 | 
					constexpr u64 CNTFREQ = 19200000;           // Value from fusee.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline s64 msToCycles(int ms) {
 | 
					inline s64 msToCycles(int ms) {
 | 
				
			||||||
    // since ms is int there is no way to overflow
 | 
					    // since ms is int there is no way to overflow
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user