Jit64: Inline GP writes.

As we're down to 4 instructions now, it is always worth to inline those writes.
This commit is contained in:
degasus 2017-11-18 14:45:09 +01:00
parent 4feddd7748
commit 36ad887a19
6 changed files with 15 additions and 56 deletions

View File

@ -222,14 +222,6 @@ void Jit64AsmRoutineManager::ResetStack(X64CodeBlock& emitter)
void Jit64AsmRoutineManager::GenerateCommon() void Jit64AsmRoutineManager::GenerateCommon()
{ {
fifoDirectWrite8 = AlignCode4();
GenFifoWrite(8);
fifoDirectWrite16 = AlignCode4();
GenFifoWrite(16);
fifoDirectWrite32 = AlignCode4();
GenFifoWrite(32);
fifoDirectWrite64 = AlignCode4();
GenFifoWrite(64);
frsqrte = AlignCode4(); frsqrte = AlignCode4();
GenFrsqrte(); GenFrsqrte();
fres = AlignCode4(); fres = AlignCode4();

View File

@ -203,28 +203,6 @@ bool EmuCodeBlock::UnsafeLoadToReg(X64Reg reg_value, OpArg opAddress, int access
return offsetAddedToAddress; return offsetAddedToAddress;
} }
void EmuCodeBlock::UnsafeWriteGatherPipe(int accessSize)
{
// No need to protect these, they don't touch any state
// question - should we inline them instead? Pro: Lose a CALL Con: Code bloat
switch (accessSize)
{
case 8:
CALL(g_jit->GetAsmRoutines()->fifoDirectWrite8);
break;
case 16:
CALL(g_jit->GetAsmRoutines()->fifoDirectWrite16);
break;
case 32:
CALL(g_jit->GetAsmRoutines()->fifoDirectWrite32);
break;
case 64:
CALL(g_jit->GetAsmRoutines()->fifoDirectWrite64);
break;
}
g_jit->js.fifoBytesSinceCheck += accessSize >> 3;
}
// Visitor that generates code to read a MMIO value. // Visitor that generates code to read a MMIO value.
template <typename T> template <typename T>
class MMIOReadCodeGenerator : public MMIO::ReadHandlingMethodVisitor<T> class MMIOReadCodeGenerator : public MMIO::ReadHandlingMethodVisitor<T>
@ -622,10 +600,22 @@ bool EmuCodeBlock::WriteToConstAddress(int accessSize, OpArg arg, u32 address,
// fun tricks... // fun tricks...
if (g_jit->jo.optimizeGatherPipe && PowerPC::IsOptimizableGatherPipeWrite(address)) if (g_jit->jo.optimizeGatherPipe && PowerPC::IsOptimizableGatherPipeWrite(address))
{ {
if (!arg.IsSimpleReg(RSCRATCH)) X64Reg arg_reg = RSCRATCH;
MOV(accessSize, R(RSCRATCH), arg);
UnsafeWriteGatherPipe(accessSize); // With movbe, we can store inplace without temporary register
if (arg.IsSimpleReg() && cpu_info.bMOVBE)
arg_reg = arg.GetSimpleReg();
if (!arg.IsSimpleReg(arg_reg))
MOV(accessSize, R(arg_reg), arg);
// And store it in the gather pipe
MOV(64, R(RSCRATCH2), PPCSTATE(gather_pipe_ptr));
SwapAndStore(accessSize, MatR(RSCRATCH2), arg_reg);
ADD(64, R(RSCRATCH2), Imm8(accessSize >> 3));
MOV(64, PPCSTATE(gather_pipe_ptr), R(RSCRATCH2));
g_jit->js.fifoBytesSinceCheck += accessSize >> 3;
return false; return false;
} }
else if (PowerPC::IsOptimizableRAMAddress(address)) else if (PowerPC::IsOptimizableRAMAddress(address))

View File

@ -61,7 +61,6 @@ public:
bool UnsafeLoadToReg(Gen::X64Reg reg_value, Gen::OpArg opAddress, int accessSize, s32 offset, bool UnsafeLoadToReg(Gen::X64Reg reg_value, Gen::OpArg opAddress, int accessSize, s32 offset,
bool signExtend, Gen::MovInfo* info = nullptr); bool signExtend, Gen::MovInfo* info = nullptr);
void UnsafeWriteGatherPipe(int accessSize);
// Generate a load/write from the MMIO handler for a given address. Only // Generate a load/write from the MMIO handler for a given address. Only
// call for known addresses in MMIO range (MMIO::IsMMIOAddress). // call for known addresses in MMIO range (MMIO::IsMMIOAddress).

View File

@ -24,22 +24,6 @@
using namespace Gen; using namespace Gen;
void CommonAsmRoutines::GenFifoWrite(int size)
{
const void* start = GetCodePtr();
// Assume value in RSCRATCH
MOV(64, R(RSCRATCH2), ImmPtr(&PowerPC::ppcState.gather_pipe_ptr));
MOV(64, R(RSCRATCH2), MatR(RSCRATCH2));
SwapAndStore(size, MatR(RSCRATCH2), RSCRATCH);
MOV(64, R(RSCRATCH), ImmPtr(&PowerPC::ppcState.gather_pipe_ptr));
ADD(64, R(RSCRATCH2), Imm8(size >> 3));
MOV(64, MatR(RSCRATCH), R(RSCRATCH2));
RET();
JitRegister::Register(start, GetCodePtr(), "JIT_FifoWrite_%i", size);
}
void CommonAsmRoutines::GenFrsqrte() void CommonAsmRoutines::GenFrsqrte()
{ {
const void* start = GetCodePtr(); const void* start = GetCodePtr();

View File

@ -24,7 +24,6 @@ private:
class CommonAsmRoutines : public CommonAsmRoutinesBase, public QuantizedMemoryRoutines class CommonAsmRoutines : public CommonAsmRoutinesBase, public QuantizedMemoryRoutines
{ {
public: public:
void GenFifoWrite(int size);
void GenFrsqrte(); void GenFrsqrte();
void GenFres(); void GenFres();
void GenMfcr(); void GenMfcr();

View File

@ -15,11 +15,6 @@ alignas(16) extern const float m_dequantizeTableS[128];
class CommonAsmRoutinesBase class CommonAsmRoutinesBase
{ {
public: public:
const u8* fifoDirectWrite8;
const u8* fifoDirectWrite16;
const u8* fifoDirectWrite32;
const u8* fifoDirectWrite64;
const u8* enterCode; const u8* enterCode;
const u8* dispatcherMispredictedBLR; const u8* dispatcherMispredictedBLR;