Finalize constexpr ppu_decoder<> thing

Move SSSE3 checks to runtime in PPUInterpreter.cpp
This commit is contained in:
Nekotekina 2020-03-24 20:07:35 +03:00
parent fd3522436a
commit 471db3219d
4 changed files with 29 additions and 143 deletions

View file

@ -5,6 +5,7 @@
#include "Emu/system_config.h"
#include "PPUThread.h"
#include "Utilities/asm.h"
#include "Utilities/sysinfo.h"
#include "Emu/Cell/Common.h"
#include <cmath>
@ -21,6 +22,8 @@
#define SSSE3_FUNC __attribute__((__target__("ssse3")))
#endif
const bool s_use_ssse3 = utils::has_ssse3();
inline u64 dup32(u32 x) { return x | static_cast<u64>(x) << 32; }
// Write values to CR field
@ -123,7 +126,7 @@ extern __m128 sse_log2_ps(__m128 A)
return _mm_add_ps(_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(x5, x6), x7), x4), _c), _mm_add_ps(_mm_mul_ps(x4, _c), x8));
}
extern __m128i sse_pshufb(__m128i data, __m128i index)
extern SAFE_BUFFERS __m128i sse_pshufb(__m128i data, __m128i index)
{
v128 m = v128::fromV(_mm_and_si128(index, _mm_set1_epi8(0xf)));
v128 a = v128::fromV(data);
@ -146,7 +149,7 @@ extern SSSE3_FUNC __m128i sse_altivec_vperm(__m128i A, __m128i B, __m128i C)
return _mm_or_si128(_mm_and_si128(mask, sa), _mm_andnot_si128(mask, sb));
}
extern __m128i sse_altivec_vperm_v0(__m128i A, __m128i B, __m128i C)
extern SAFE_BUFFERS __m128i sse_altivec_vperm_v0(__m128i A, __m128i B, __m128i C)
{
__m128i ab[2]{B, A};
v128 index = v128::fromV(_mm_andnot_si128(C, _mm_set1_epi8(0x1f)));
@ -1427,15 +1430,11 @@ bool ppu_interpreter::VOR(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::VPERM(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::VPERM(ppu_thread& ppu, ppu_opcode_t op)
{
ppu.vr[op.vd].vi = sse_altivec_vperm_v0(ppu.vr[op.va].vi, ppu.vr[op.vb].vi, ppu.vr[op.vc].vi);
return true;
}
bool ppu_interpreter_fast::VPERM(ppu_thread& ppu, ppu_opcode_t op)
{
ppu.vr[op.vd].vi = sse_altivec_vperm(ppu.vr[op.va].vi, ppu.vr[op.vb].vi, ppu.vr[op.vc].vi);
ppu.vr[op.vd].vi = s_use_ssse3
? sse_altivec_vperm(ppu.vr[op.va].vi, ppu.vr[op.vb].vi, ppu.vr[op.vc].vi)
: sse_altivec_vperm_v0(ppu.vr[op.va].vi, ppu.vr[op.vb].vi, ppu.vr[op.vc].vi);
return true;
}
@ -3959,17 +3958,10 @@ bool ppu_interpreter::DIVW(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::LVLX(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::LVLX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.vr[op.vd].vi = sse_cellbe_lvlx_v0(addr);
return true;
}
bool ppu_interpreter_fast::LVLX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.vr[op.vd].vi = sse_cellbe_lvlx(addr);
ppu.vr[op.vd].vi = s_use_ssse3 ? sse_cellbe_lvlx(addr) : sse_cellbe_lvlx_v0(addr);
return true;
}
@ -4030,17 +4022,10 @@ bool ppu_interpreter::SRD(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::LVRX(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::LVRX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.vr[op.vd].vi = sse_cellbe_lvrx_v0(addr);
return true;
}
bool ppu_interpreter_fast::LVRX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.vr[op.vd].vi = sse_cellbe_lvrx(addr);
ppu.vr[op.vd].vi = s_use_ssse3 ? sse_cellbe_lvrx(addr) : sse_cellbe_lvrx_v0(addr);
return true;
}
@ -4105,17 +4090,10 @@ bool ppu_interpreter::LFDUX(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::STVLX(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::STVLX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
sse_cellbe_stvlx_v0(addr, ppu.vr[op.vs].vi);
return true;
}
bool ppu_interpreter_fast::STVLX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
sse_cellbe_stvlx(addr, ppu.vr[op.vs].vi);
s_use_ssse3 ? sse_cellbe_stvlx(addr, ppu.vr[op.vs].vi) : sse_cellbe_stvlx_v0(addr, ppu.vr[op.vs].vi);
return true;
}
@ -4160,17 +4138,10 @@ bool ppu_interpreter::STFSX(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::STVRX(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::STVRX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
sse_cellbe_stvrx_v0(addr, ppu.vr[op.vs].vi);
return true;
}
bool ppu_interpreter_fast::STVRX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
sse_cellbe_stvrx(addr, ppu.vr[op.vs].vi);
s_use_ssse3 ? sse_cellbe_stvrx(addr, ppu.vr[op.vs].vi) : sse_cellbe_stvrx_v0(addr, ppu.vr[op.vs].vi);
return true;
}
@ -4227,12 +4198,7 @@ bool ppu_interpreter::STFDUX(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::LVLXL(ppu_thread& ppu, ppu_opcode_t op)
{
return LVLX(ppu, op);
}
bool ppu_interpreter_fast::LVLXL(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::LVLXL(ppu_thread& ppu, ppu_opcode_t op)
{
return LVLX(ppu, op);
}
@ -4282,12 +4248,7 @@ bool ppu_interpreter::SRAD(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::LVRXL(ppu_thread& ppu, ppu_opcode_t op)
{
return LVRX(ppu, op);
}
bool ppu_interpreter_fast::LVRXL(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::LVRXL(ppu_thread& ppu, ppu_opcode_t op)
{
return LVRX(ppu, op);
}
@ -4324,12 +4285,7 @@ bool ppu_interpreter::EIEIO(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::STVLXL(ppu_thread& ppu, ppu_opcode_t op)
{
return STVLX(ppu, op);
}
bool ppu_interpreter_fast::STVLXL(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::STVLXL(ppu_thread& ppu, ppu_opcode_t op)
{
return STVLX(ppu, op);
}
@ -4348,12 +4304,7 @@ bool ppu_interpreter::EXTSH(ppu_thread& ppu, ppu_opcode_t op)
return true;
}
bool ppu_interpreter_precise::STVRXL(ppu_thread& ppu, ppu_opcode_t op)
{
return STVRX(ppu, op);
}
bool ppu_interpreter_fast::STVRXL(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::STVRXL(ppu_thread& ppu, ppu_opcode_t op)
{
return STVRX(ppu, op);
}