mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-06 06:55:09 +00:00
moved tsc and asm utilities to rx
This commit is contained in:
parent
bd215fab92
commit
640df36c48
121 changed files with 706 additions and 1225 deletions
|
|
@ -6,19 +6,10 @@
|
|||
#include <functional>
|
||||
#include <limits>
|
||||
#include <system_error>
|
||||
#include <thread>
|
||||
#include <type_traits>
|
||||
#include "asm.hpp"
|
||||
|
||||
namespace rx {
|
||||
inline void yield() { std::this_thread::yield(); }
|
||||
inline void relax() {
|
||||
#if defined(__GNUC__) && (defined __i386__ || defined __x86_64__)
|
||||
__builtin_ia32_pause();
|
||||
#else
|
||||
yield();
|
||||
#endif
|
||||
}
|
||||
|
||||
static constexpr auto kRelaxSpinCount = 12;
|
||||
static constexpr auto kSpinCount = 16;
|
||||
|
||||
|
|
@ -31,7 +22,7 @@ bool try_spin_wait(auto &&pred) {
|
|||
}
|
||||
|
||||
if (i < kRelaxSpinCount) {
|
||||
relax();
|
||||
pause();
|
||||
} else {
|
||||
yield();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace rx {
|
||||
inline constexpr std::uint64_t alignUp(std::uint64_t value,
|
||||
std::uint64_t alignment) {
|
||||
return (value + (alignment - 1)) & ~(alignment - 1);
|
||||
template <typename T, typename U>
|
||||
requires std::is_unsigned_v<T>
|
||||
inline constexpr std::make_unsigned_t<std::common_type_t<T, U>>
|
||||
alignUp(T value, U alignment) {
|
||||
return static_cast<std::make_unsigned_t<std::common_type_t<T, U>>>(
|
||||
(value + (alignment - 1)) & ~(alignment - 1));
|
||||
}
|
||||
inline constexpr std::uint64_t alignDown(std::uint64_t value,
|
||||
std::uint64_t alignment) {
|
||||
return value & ~(alignment - 1);
|
||||
|
||||
template <typename T, typename U>
|
||||
requires std::is_unsigned_v<T>
|
||||
inline constexpr std::make_unsigned_t<std::common_type_t<T, U>>
|
||||
alignDown(T value, U alignment) {
|
||||
return static_cast<std::make_unsigned_t<std::common_type_t<T, U>>>(
|
||||
value & ~(alignment - 1));
|
||||
}
|
||||
} // namespace rx
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "rx/tsc.hpp"
|
||||
#include "types.hpp"
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
extern bool g_use_rtm;
|
||||
|
|
@ -275,6 +277,16 @@ inline void pause() {
|
|||
#endif
|
||||
}
|
||||
|
||||
inline void yield() { std::this_thread::yield(); }
|
||||
|
||||
// Synchronization helper (cache-friendly busy waiting)
|
||||
inline void busy_wait(usz cycles = 3000) {
|
||||
const u64 stop = get_tsc() + cycles;
|
||||
do
|
||||
pause();
|
||||
while (get_tsc() < stop);
|
||||
}
|
||||
|
||||
// Align to power of 2
|
||||
template <typename T, typename U>
|
||||
requires std::is_unsigned_v<T>
|
||||
|
|
@ -312,12 +324,6 @@ constexpr T rational_mul(T value, std::type_identity_t<T> numerator,
|
|||
return static_cast<T>(value * u64{numerator} / u64{denominator});
|
||||
}
|
||||
|
||||
#if is_u128_emulated
|
||||
if constexpr (sizeof(T) <= sizeof(u128) / 2) {
|
||||
return static_cast<T>(u128_from_mul(value, numerator) / u64{denominator});
|
||||
}
|
||||
#endif
|
||||
|
||||
return static_cast<T>(value / denominator * numerator +
|
||||
(value % denominator) * numerator / denominator);
|
||||
}
|
||||
|
|
|
|||
28
rx/include/rx/tsc.hpp
Normal file
28
rx/include/rx/tsc.hpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef _M_X64
|
||||
#ifdef _MSC_VER
|
||||
extern "C" std::uint64_t __rdtsc();
|
||||
#else
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace rx {
|
||||
inline std::uint64_t get_tsc() {
|
||||
#if defined(ARCH_ARM64)
|
||||
std::uint64_t r = 0;
|
||||
__asm__ volatile("mrs %0, cntvct_el0" : "=r"(r));
|
||||
return r;
|
||||
#elif defined(_M_X64)
|
||||
return __rdtsc();
|
||||
#elif defined(ARCH_X64)
|
||||
return __builtin_ia32_rdtsc();
|
||||
#else
|
||||
#error "Missing rx::get_tsc() implementation"
|
||||
#endif
|
||||
}
|
||||
} // namespace rx
|
||||
|
|
@ -106,20 +106,6 @@ template <typename F> fn_helper(F &&f) -> fn_helper<F>;
|
|||
[[maybe_unused]] auto &&z, \
|
||||
[[maybe_unused]] auto &&w) { return (__VA_ARGS__); })
|
||||
|
||||
#if __cpp_lib_bit_cast < 201806L
|
||||
namespace std {
|
||||
template <typename To, typename From>
|
||||
[[nodiscard]] constexpr To bit_cast(const From &from) noexcept {
|
||||
return __builtin_bit_cast(To, from);
|
||||
}
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
#if defined(__INTELLISENSE__) || (defined(__clang__) && (__clang_major__ <= 16))
|
||||
#define consteval constexpr
|
||||
#define constinit
|
||||
#endif
|
||||
|
||||
// FIXME: move to ps3 kernel implementation
|
||||
using schar = signed char;
|
||||
using uchar = unsigned char;
|
||||
|
|
@ -206,9 +192,9 @@ public:
|
|||
};
|
||||
|
||||
#if defined(ARCH_X64) && !defined(_MSC_VER)
|
||||
using __m128i = long long __attribute__((vector_size(16)));
|
||||
using __m128d = double __attribute__((vector_size(16)));
|
||||
using __m128 = float __attribute__((vector_size(16)));
|
||||
using __m128i = long long __attribute__((vector_size(16), aligned(16)));
|
||||
using __m128d = double __attribute__((vector_size(16), aligned(16)));
|
||||
using __m128 = float __attribute__((vector_size(16), aligned(16)));
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue