Make spu_decoder<> objects constexpr

This commit is contained in:
Nekotekina 2020-03-24 11:40:22 +03:00
parent eb1de04ca8
commit a936533eb1
6 changed files with 29 additions and 31 deletions

View file

@ -22,8 +22,8 @@
#define SPU_OFF_16(x, ...) asmjit::x86::word_ptr(*cpu, offset32(&spu_thread::x, ##__VA_ARGS__)) #define SPU_OFF_16(x, ...) asmjit::x86::word_ptr(*cpu, offset32(&spu_thread::x, ##__VA_ARGS__))
#define SPU_OFF_8(x, ...) asmjit::x86::byte_ptr(*cpu, offset32(&spu_thread::x, ##__VA_ARGS__)) #define SPU_OFF_8(x, ...) asmjit::x86::byte_ptr(*cpu, offset32(&spu_thread::x, ##__VA_ARGS__))
extern const spu_decoder<spu_interpreter_fast> g_spu_interpreter_fast; // TODO: avoid constexpr spu_decoder<spu_interpreter_fast> g_spu_interpreter_fast; // TODO: avoid
const spu_decoder<spu_recompiler> s_spu_decoder; constexpr spu_decoder<spu_recompiler> s_spu_decoder;
extern u64 get_timebased_time(); extern u64 get_timebased_time();

View file

@ -1,7 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "SPUDisAsm.h" #include "SPUDisAsm.h"
const spu_decoder<SPUDisAsm> s_spu_disasm; constexpr spu_decoder<SPUDisAsm> s_spu_disasm;
u32 SPUDisAsm::disasm(u32 pc) u32 SPUDisAsm::disasm(u32 pc)
{ {

View file

@ -1691,7 +1691,7 @@ bool spu_interpreter::SELB(spu_thread& spu, spu_opcode_t op)
return true; return true;
} }
static bool SHUFB_(spu_thread& spu, spu_opcode_t op) bool spu_interpreter::SHUFB(spu_thread& spu, spu_opcode_t op)
{ {
__m128i ab[2]{spu.gpr[op.rb].vi, spu.gpr[op.ra].vi}; __m128i ab[2]{spu.gpr[op.rb].vi, spu.gpr[op.ra].vi};
v128 c = spu.gpr[op.rc]; v128 c = spu.gpr[op.rc];
@ -1714,7 +1714,7 @@ static bool SHUFB_(spu_thread& spu, spu_opcode_t op)
return true; return true;
} }
const spu_inter_func_t spu_interpreter::SHUFB = !utils::has_ssse3() ? &SHUFB_ : build_function_asm<spu_inter_func_t>([](asmjit::X86Assembler& c, auto& args) const spu_inter_func_t optimized_shufb = build_function_asm<spu_inter_func_t>([](asmjit::X86Assembler& c, auto& args)
{ {
using namespace asmjit; using namespace asmjit;
@ -2645,7 +2645,3 @@ bool spu_interpreter_precise::FNMS(spu_thread& spu, spu_opcode_t op) { ::FMA(spu
bool spu_interpreter_precise::FMA(spu_thread& spu, spu_opcode_t op) { ::FMA(spu, op, false, false); return true; } bool spu_interpreter_precise::FMA(spu_thread& spu, spu_opcode_t op) { ::FMA(spu, op, false, false); return true; }
bool spu_interpreter_precise::FMS(spu_thread& spu, spu_opcode_t op) { ::FMA(spu, op, false, true); return true; } bool spu_interpreter_precise::FMS(spu_thread& spu, spu_opcode_t op) { ::FMA(spu, op, false, true); return true; }
extern const spu_decoder<spu_interpreter_precise> g_spu_interpreter_precise{};
extern const spu_decoder<spu_interpreter_fast> g_spu_interpreter_fast{};

View file

@ -175,7 +175,7 @@ struct spu_interpreter
static bool HBRR(spu_thread&, spu_opcode_t); static bool HBRR(spu_thread&, spu_opcode_t);
static bool ILA(spu_thread&, spu_opcode_t); static bool ILA(spu_thread&, spu_opcode_t);
static bool SELB(spu_thread&, spu_opcode_t); static bool SELB(spu_thread&, spu_opcode_t);
static const spu_inter_func_t SHUFB; static bool SHUFB(spu_thread&, spu_opcode_t);
static bool MPYA(spu_thread&, spu_opcode_t); static bool MPYA(spu_thread&, spu_opcode_t);
static bool DFCGT(spu_thread&, spu_opcode_t); static bool DFCGT(spu_thread&, spu_opcode_t);
static bool DFCMGT(spu_thread&, spu_opcode_t); static bool DFCMGT(spu_thread&, spu_opcode_t);

View file

@ -46,7 +46,7 @@ template <typename D, typename T = decltype(&D::UNK)>
class spu_decoder class spu_decoder
{ {
// Fast lookup table // Fast lookup table
std::array<T, 2048> m_table; std::array<T, 2048> m_table{};
struct instruction_info struct instruction_info
{ {
@ -54,14 +54,14 @@ class spu_decoder
u32 value; u32 value;
T pointer; T pointer;
instruction_info(u32 m, u32 v, T p) constexpr instruction_info(u32 m, u32 v, T p)
: magn(m) : magn(m)
, value(v) , value(v)
, pointer(p) , pointer(p)
{ {
} }
instruction_info(u32 m, u32 v, const T* p) constexpr instruction_info(u32 m, u32 v, const T* p)
: magn(m) : magn(m)
, value(v) , value(v)
, pointer(*p) , pointer(*p)
@ -70,7 +70,7 @@ class spu_decoder
}; };
public: public:
spu_decoder() constexpr spu_decoder()
{ {
const std::initializer_list<instruction_info> instructions const std::initializer_list<instruction_info> instructions
{ {
@ -275,7 +275,10 @@ public:
{ 7, 0xf, &D::FMS }, { 7, 0xf, &D::FMS },
}; };
m_table.fill(&D::UNK); for (auto& x : m_table)
{
x = &D::UNK;
}
for (auto& entry : instructions) for (auto& entry : instructions)
{ {
@ -286,12 +289,6 @@ public:
} }
} }
template <typename F>
spu_decoder(F&& init) : spu_decoder()
{
init(m_table);
}
const std::array<T, 2048>& get_table() const const std::array<T, 2048>& get_table() const
{ {
return m_table; return m_table;

View file

@ -22,12 +22,12 @@ extern atomic_t<const char*> g_progr;
extern atomic_t<u32> g_progr_ptotal; extern atomic_t<u32> g_progr_ptotal;
extern atomic_t<u32> g_progr_pdone; extern atomic_t<u32> g_progr_pdone;
const spu_decoder<spu_itype> s_spu_itype; constexpr spu_decoder<spu_itype> s_spu_itype;
const spu_decoder<spu_iname> s_spu_iname; constexpr spu_decoder<spu_iname> s_spu_iname;
const spu_decoder<spu_iflag> s_spu_iflag; constexpr spu_decoder<spu_iflag> s_spu_iflag;
extern const spu_decoder<spu_interpreter_precise> g_spu_interpreter_precise; constexpr spu_decoder<spu_interpreter_precise> g_spu_interpreter_precise;
extern const spu_decoder<spu_interpreter_fast> g_spu_interpreter_fast; constexpr spu_decoder<spu_interpreter_fast> g_spu_interpreter_fast;
extern u64 get_timebased_time(); extern u64 get_timebased_time();
@ -4603,7 +4603,7 @@ public:
} }
// Execute recompiler function (TODO) // Execute recompiler function (TODO)
(this->*g_decoder.decode(op))({op}); (this->*decode(op))({op});
} }
// Finalize block with fallthrough if necessary // Finalize block with fallthrough if necessary
@ -4999,7 +4999,7 @@ public:
if (itype & spu_itype::branch) if (itype & spu_itype::branch)
{ {
// Instruction changes pc - change order. // Instruction changes pc - change order.
(this->*g_decoder.decode(op))({op}); (this->*decode(op))({op});
if (m_interp_bblock) if (m_interp_bblock)
{ {
@ -5030,7 +5030,7 @@ public:
} }
// Normal instruction. // Normal instruction.
(this->*g_decoder.decode(op))({op}); (this->*decode(op))({op});
if (check && !m_ir->GetInsertBlock()->getTerminator()) if (check && !m_ir->GetInsertBlock()->getTerminator())
{ {
@ -8277,7 +8277,7 @@ public:
} }
} }
static const spu_decoder<spu_llvm_recompiler> g_decoder; static decltype(&spu_llvm_recompiler::UNK) decode(u32 op);
}; };
std::unique_ptr<spu_recompiler_base> spu_recompiler_base::make_llvm_recompiler(u8 magn) std::unique_ptr<spu_recompiler_base> spu_recompiler_base::make_llvm_recompiler(u8 magn)
@ -8285,7 +8285,12 @@ std::unique_ptr<spu_recompiler_base> spu_recompiler_base::make_llvm_recompiler(u
return std::make_unique<spu_llvm_recompiler>(magn); return std::make_unique<spu_llvm_recompiler>(magn);
} }
DECLARE(spu_llvm_recompiler::g_decoder); constexpr spu_decoder<spu_llvm_recompiler> g_spu_llvm_decoder;
decltype(&spu_llvm_recompiler::UNK) spu_llvm_recompiler::decode(u32 op)
{
return g_spu_llvm_decoder.decode(op);
}
#else #else