1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

Remove built_function

With today's branch prediction techniques, it's hardly useful.
This commit is contained in:
Nekotekina 2022-01-23 15:20:07 +03:00
parent d2897bc6a0
commit 12c83b340d
11 changed files with 17 additions and 112 deletions

View File

@ -263,100 +263,6 @@ inline FT build_function_asm(std::string_view name, F&& builder)
return reinterpret_cast<FT>(uptr(result)); return reinterpret_cast<FT>(uptr(result));
} }
#if !defined(ARCH_X64) || defined(__APPLE__)
template <typename FT, usz = 4096>
class built_function
{
FT m_func;
public:
built_function(const built_function&) = delete;
built_function& operator=(const built_function&) = delete;
template <typename F>
built_function(std::string_view name, F&& builder,
u32 line = __builtin_LINE(),
u32 col = __builtin_COLUMN(),
const char* file = __builtin_FILE(),
const char* func = __builtin_FUNCTION())
: m_func(ensure(build_function_asm<FT>(name, std::forward<F>(builder)), const_str(), line, col, file, func))
{
}
operator FT() const noexcept
{
return m_func;
}
template <typename... Args>
auto operator()(Args&&... args) const noexcept
{
return m_func(std::forward<Args>(args)...);
}
};
#else
template <typename FT, usz Size = 4096>
class built_function
{
alignas(4096) uchar m_data[Size];
public:
built_function(const built_function&) = delete;
built_function& operator=(const built_function&) = delete;
template <typename F>
built_function(std::string_view name, F&& builder)
{
using namespace asmjit;
inline_runtime rt(m_data, Size);
CodeHolder code;
code.init(rt.environment());
#if defined(ARCH_X64)
native_args args;
#ifdef _WIN32
args[0] = x86::rcx;
args[1] = x86::rdx;
args[2] = x86::r8;
args[3] = x86::r9;
#else
args[0] = x86::rdi;
args[1] = x86::rsi;
args[2] = x86::rdx;
args[3] = x86::rcx;
#endif
#elif defined(ARCH_ARM64)
native_args args;
args[0] = a64::x0;
args[1] = a64::x1;
args[2] = a64::x2;
args[3] = a64::x3;
#endif
native_asm compiler(&code);
compiler.addEncodingOptions(EncodingOptions::kOptimizedAlign);
builder(compiler, args);
rt.dump_name = name;
jit_announce(rt._add(&code), code.codeSize(), name);
}
operator FT() const noexcept
{
return FT(+m_data);
}
template <typename... Args>
auto operator()(Args&&... args) const noexcept
{
return FT(+m_data)(std::forward<Args>(args)...);
}
};
#endif
#ifdef LLVM_AVAILABLE #ifdef LLVM_AVAILABLE
namespace llvm namespace llvm

View File

@ -2250,7 +2250,7 @@ thread_base::native_entry thread_base::finalize(u64 _self) noexcept
thread_base::native_entry thread_base::make_trampoline(u64(*entry)(thread_base* _base)) thread_base::native_entry thread_base::make_trampoline(u64(*entry)(thread_base* _base))
{ {
return build_function_asm<native_entry>("thread_base_trampoline", [&](native_asm& c, auto& args) return build_function_asm<native_entry>("", [&](native_asm& c, auto& args)
{ {
using namespace asmjit; using namespace asmjit;

View File

@ -1947,7 +1947,7 @@ u32 ppu_function_manager::add_function(ppu_intrp_func_t function)
// Generate trampoline // Generate trampoline
#if defined(ARCH_X64) #if defined(ARCH_X64)
list2.push_back(build_function_asm<ppu_intrp_func_t>("ppu_trampolinea", [&](native_asm& c, auto& args) list2.push_back(build_function_asm<ppu_intrp_func_t>("", [&](native_asm& c, auto& args)
{ {
using namespace asmjit; using namespace asmjit;

View File

@ -146,7 +146,7 @@ static void ppu_break(ppu_thread&, ppu_opcode_t, be_t<u32>*, ppu_intrp_func*);
extern void do_cell_atomic_128_store(u32 addr, const void* to_write); extern void do_cell_atomic_128_store(u32 addr, const void* to_write);
const auto ppu_gateway = built_function<void(*)(ppu_thread*)>("ppu_gateway", [](native_asm& c, auto& args) const auto ppu_gateway = build_function_asm<void(*)(ppu_thread*)>("ppu_gateway", [](native_asm& c, auto& args)
{ {
// Gateway for PPU, converts from native to GHC calling convention, also saves RSP value for escape // Gateway for PPU, converts from native to GHC calling convention, also saves RSP value for escape
using namespace asmjit; using namespace asmjit;
@ -268,7 +268,7 @@ const extern auto ppu_escape = build_function_asm<void(*)(ppu_thread*)>("ppu_esc
void ppu_recompiler_fallback(ppu_thread& ppu); void ppu_recompiler_fallback(ppu_thread& ppu);
#if defined(ARCH_X64) #if defined(ARCH_X64)
const auto ppu_recompiler_fallback_ghc = build_function_asm<void(*)(ppu_thread& ppu)>("ppu_trampolineb", [](native_asm& c, auto& args) const auto ppu_recompiler_fallback_ghc = build_function_asm<void(*)(ppu_thread& ppu)>("", [](native_asm& c, auto& args)
{ {
using namespace asmjit; using namespace asmjit;
@ -1743,7 +1743,7 @@ extern u64 ppu_ldarx(ppu_thread& ppu, u32 addr)
return ppu_load_acquire_reservation<u64>(ppu, addr); return ppu_load_acquire_reservation<u64>(ppu, addr);
} }
const auto ppu_stcx_accurate_tx = built_function<u64(*)(u32 raddr, u64 rtime, const void* _old, u64 _new)>("ppu_stcx_accurate_tx", [](native_asm& c, auto& args) const auto ppu_stcx_accurate_tx = build_function_asm<u64(*)(u32 raddr, u64 rtime, const void* _old, u64 _new)>("ppu_stcx_accurate_tx", [](native_asm& c, auto& args)
{ {
using namespace asmjit; using namespace asmjit;

View File

@ -157,7 +157,7 @@ DECLARE(spu_runtime::tr_all) = []
return reinterpret_cast<spu_function_t>(trptr); return reinterpret_cast<spu_function_t>(trptr);
}(); }();
DECLARE(spu_runtime::g_gateway) = built_function<spu_function_t>("spu_gateway", [](native_asm& c, auto& args) DECLARE(spu_runtime::g_gateway) = build_function_asm<spu_function_t>("spu_gateway", [](native_asm& c, auto& args)
{ {
// Gateway for SPU dispatcher, converts from native to GHC calling convention, also saves RSP value for spu_escape // Gateway for SPU dispatcher, converts from native to GHC calling convention, also saves RSP value for spu_escape
using namespace asmjit; using namespace asmjit;

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Utilities/File.h" #include "Utilities/File.h"
#include "Utilities/JIT.h"
#include "Utilities/lockless.h" #include "Utilities/lockless.h"
#include "SPUThread.h" #include "SPUThread.h"
#include <vector> #include <vector>
@ -133,7 +132,7 @@ public:
static std::array<atomic_t<spu_function_t>, (1 << 20)>* const g_dispatcher; static std::array<atomic_t<spu_function_t>, (1 << 20)>* const g_dispatcher;
// Recompiler entry point // Recompiler entry point
static const built_function<spu_function_t> g_gateway; static const spu_function_t g_gateway;
// Longjmp to the end of the gateway function (native CC) // Longjmp to the end of the gateway function (native CC)
static void(*const g_escape)(spu_thread*); static void(*const g_escape)(spu_thread*);

View File

@ -439,7 +439,7 @@ std::array<u32, 2> op_branch_targets(u32 pc, spu_opcode_t op)
return res; return res;
} }
const auto spu_putllc_tx = built_function<u64(*)(u32 raddr, u64 rtime, void* _old, const void* _new)>("spu_putllc_tx", [](native_asm& c, auto& args) const auto spu_putllc_tx = build_function_asm<u64(*)(u32 raddr, u64 rtime, void* _old, const void* _new)>("spu_putllc_tx", [](native_asm& c, auto& args)
{ {
using namespace asmjit; using namespace asmjit;
@ -701,7 +701,7 @@ const auto spu_putllc_tx = built_function<u64(*)(u32 raddr, u64 rtime, void* _ol
#endif #endif
}); });
const auto spu_putlluc_tx = built_function<u64(*)(u32 raddr, const void* rdata, u64* _stx, u64* _ftx)>("spu_putlluc_tx", [](native_asm& c, auto& args) const auto spu_putlluc_tx = build_function_asm<u64(*)(u32 raddr, const void* rdata, u64* _stx, u64* _ftx)>("spu_putlluc_tx", [](native_asm& c, auto& args)
{ {
using namespace asmjit; using namespace asmjit;
@ -831,7 +831,7 @@ const auto spu_putlluc_tx = built_function<u64(*)(u32 raddr, const void* rdata,
#endif #endif
}); });
const auto spu_getllar_tx = built_function<u64(*)(u32 raddr, void* rdata, cpu_thread* _cpu, u64 rtime)>("spu_getllar_tx", [](native_asm& c, auto& args) const auto spu_getllar_tx = build_function_asm<u64(*)(u32 raddr, void* rdata, cpu_thread* _cpu, u64 rtime)>("spu_getllar_tx", [](native_asm& c, auto& args)
{ {
using namespace asmjit; using namespace asmjit;

View File

@ -7,11 +7,11 @@
#include "Utilities/mutex.h" #include "Utilities/mutex.h"
#include "Utilities/Thread.h" #include "Utilities/Thread.h"
#include "Utilities/address_range.h" #include "Utilities/address_range.h"
#include "Utilities/JIT.h"
#include "Emu/CPU/CPUThread.h" #include "Emu/CPU/CPUThread.h"
#include "Emu/RSX/RSXThread.h" #include "Emu/RSX/RSXThread.h"
#include "Emu/Cell/SPURecompiler.h" #include "Emu/Cell/SPURecompiler.h"
#include "Emu/perf_meter.hpp" #include "Emu/perf_meter.hpp"
#include <thread>
#include <deque> #include <deque>
#include <shared_mutex> #include <shared_mutex>

View File

@ -5,6 +5,7 @@
#include "util/to_endian.hpp" #include "util/to_endian.hpp"
#include "util/sysinfo.hpp" #include "util/sysinfo.hpp"
#include "Utilities/JIT.h"
#include "util/asm.hpp" #include "util/asm.hpp"
#if defined(ARCH_X64) #if defined(ARCH_X64)
@ -284,9 +285,9 @@ namespace
#endif #endif
} }
built_function<void(*)(u32*, const u32*, u32)> copy_data_swap_u32("copy_data_swap_u32", &build_copy_data_swap_u32<false>); DECLARE(copy_data_swap_u32) = build_function_asm<void(*)(u32*, const u32*, u32)>("copy_data_swap_u32", &build_copy_data_swap_u32<false>);
built_function<bool(*)(u32*, const u32*, u32)> copy_data_swap_u32_cmp("copy_data_swap_u32_cmp", &build_copy_data_swap_u32<true>); DECLARE(copy_data_swap_u32_cmp) = build_function_asm<bool(*)(u32*, const u32*, u32)>("copy_data_swap_u32_cmp", &build_copy_data_swap_u32<true>);
namespace namespace
{ {

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "../gcm_enums.h" #include "../gcm_enums.h"
#include "Utilities/JIT.h"
#include <span> #include <span>
@ -51,7 +50,7 @@ void stream_vector(void *dst, u32 x, u32 y, u32 z, u32 w);
void stream_vector_from_memory(void *dst, void *src); void stream_vector_from_memory(void *dst, void *src);
// Copy and swap data in 32-bit units // Copy and swap data in 32-bit units
extern built_function<void(*)(u32*, const u32*, u32)> copy_data_swap_u32; extern void(*const copy_data_swap_u32)(u32*, const u32*, u32);
// Copy and swap data in 32-bit units, return true if changed // Copy and swap data in 32-bit units, return true if changed
extern built_function<bool(*)(u32*, const u32*, u32)> copy_data_swap_u32_cmp; extern bool(*const copy_data_swap_u32_cmp)(u32*, const u32*, u32);

View File

@ -2265,7 +2265,7 @@ namespace utils
#if defined(ARCH_X64) #if defined(ARCH_X64)
template <uint Mode> template <uint Mode>
inline built_function<__m128(*)(__m128)> sse41_roundf("sse41_roundf", [](native_asm& c, native_args&) const auto sse41_roundf = build_function_asm<__m128(*)(__m128)>("sse41_roundf", [](native_asm& c, native_args&)
{ {
static_assert(Mode < 4); static_assert(Mode < 4);
using namespace asmjit; using namespace asmjit;