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:
parent
4feddd7748
commit
36ad887a19
|
@ -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();
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue