Merge pull request #5257 from MerryMage/gpfifo2
GPFifo: Use a pointer instead of an index
This commit is contained in:
commit
05fec44ff5
|
@ -28,52 +28,65 @@ namespace GPFifo
|
|||
// the same function could use both methods. Compile 2 different versions of each such block?
|
||||
|
||||
// More room for the fastmodes
|
||||
alignas(32) u8 m_gatherPipe[GATHER_PIPE_SIZE * 16];
|
||||
alignas(32) static u8 s_gather_pipe[GATHER_PIPE_SIZE * 16];
|
||||
|
||||
// pipe counter
|
||||
u32 m_gatherPipeCount = 0;
|
||||
// pipe pointer
|
||||
u8* g_gather_pipe_ptr = s_gather_pipe;
|
||||
|
||||
static size_t GetGatherPipeCount()
|
||||
{
|
||||
return g_gather_pipe_ptr - s_gather_pipe;
|
||||
}
|
||||
|
||||
static void SetGatherPipeCount(size_t size)
|
||||
{
|
||||
g_gather_pipe_ptr = s_gather_pipe + size;
|
||||
}
|
||||
|
||||
void DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_gatherPipe);
|
||||
p.Do(m_gatherPipeCount);
|
||||
p.Do(s_gather_pipe);
|
||||
u32 pipe_count = static_cast<u32>(GetGatherPipeCount());
|
||||
p.Do(pipe_count);
|
||||
SetGatherPipeCount(pipe_count);
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
ResetGatherPipe();
|
||||
memset(m_gatherPipe, 0, sizeof(m_gatherPipe));
|
||||
memset(s_gather_pipe, 0, sizeof(s_gather_pipe));
|
||||
}
|
||||
|
||||
bool IsEmpty()
|
||||
{
|
||||
return m_gatherPipeCount == 0;
|
||||
return GetGatherPipeCount() == 0;
|
||||
}
|
||||
|
||||
void ResetGatherPipe()
|
||||
{
|
||||
m_gatherPipeCount = 0;
|
||||
SetGatherPipeCount(0);
|
||||
}
|
||||
|
||||
static void UpdateGatherPipe()
|
||||
{
|
||||
u32 cnt;
|
||||
u8* curMem = Memory::GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
|
||||
for (cnt = 0; m_gatherPipeCount >= GATHER_PIPE_SIZE; cnt += GATHER_PIPE_SIZE)
|
||||
size_t pipe_count = GetGatherPipeCount();
|
||||
size_t processed;
|
||||
u8* cur_mem = Memory::GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
|
||||
for (processed = 0; pipe_count >= GATHER_PIPE_SIZE; processed += GATHER_PIPE_SIZE)
|
||||
{
|
||||
// copy the GatherPipe
|
||||
memcpy(curMem, m_gatherPipe + cnt, GATHER_PIPE_SIZE);
|
||||
m_gatherPipeCount -= GATHER_PIPE_SIZE;
|
||||
memcpy(cur_mem, s_gather_pipe + processed, GATHER_PIPE_SIZE);
|
||||
pipe_count -= GATHER_PIPE_SIZE;
|
||||
|
||||
// increase the CPUWritePointer
|
||||
if (ProcessorInterface::Fifo_CPUWritePointer == ProcessorInterface::Fifo_CPUEnd)
|
||||
{
|
||||
ProcessorInterface::Fifo_CPUWritePointer = ProcessorInterface::Fifo_CPUBase;
|
||||
curMem = Memory::GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
|
||||
cur_mem = Memory::GetPointer(ProcessorInterface::Fifo_CPUWritePointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
curMem += GATHER_PIPE_SIZE;
|
||||
cur_mem += GATHER_PIPE_SIZE;
|
||||
ProcessorInterface::Fifo_CPUWritePointer += GATHER_PIPE_SIZE;
|
||||
}
|
||||
|
||||
|
@ -81,12 +94,13 @@ static void UpdateGatherPipe()
|
|||
}
|
||||
|
||||
// move back the spill bytes
|
||||
memmove(m_gatherPipe, m_gatherPipe + cnt, m_gatherPipeCount);
|
||||
memmove(s_gather_pipe, s_gather_pipe + processed, pipe_count);
|
||||
SetGatherPipeCount(pipe_count);
|
||||
}
|
||||
|
||||
void FastCheckGatherPipe()
|
||||
{
|
||||
if (m_gatherPipeCount >= GATHER_PIPE_SIZE)
|
||||
if (GetGatherPipeCount() >= GATHER_PIPE_SIZE)
|
||||
{
|
||||
UpdateGatherPipe();
|
||||
}
|
||||
|
@ -94,7 +108,7 @@ void FastCheckGatherPipe()
|
|||
|
||||
void CheckGatherPipe()
|
||||
{
|
||||
if (m_gatherPipeCount >= GATHER_PIPE_SIZE)
|
||||
if (GetGatherPipeCount() >= GATHER_PIPE_SIZE)
|
||||
{
|
||||
UpdateGatherPipe();
|
||||
|
||||
|
@ -129,29 +143,29 @@ void Write64(const u64 value)
|
|||
|
||||
void FastWrite8(const u8 value)
|
||||
{
|
||||
m_gatherPipe[m_gatherPipeCount] = value;
|
||||
++m_gatherPipeCount;
|
||||
*g_gather_pipe_ptr = value;
|
||||
g_gather_pipe_ptr += sizeof(u8);
|
||||
}
|
||||
|
||||
void FastWrite16(u16 value)
|
||||
{
|
||||
value = Common::swap16(value);
|
||||
std::memcpy(&m_gatherPipe[m_gatherPipeCount], &value, sizeof(u16));
|
||||
m_gatherPipeCount += sizeof(u16);
|
||||
std::memcpy(g_gather_pipe_ptr, &value, sizeof(u16));
|
||||
g_gather_pipe_ptr += sizeof(u16);
|
||||
}
|
||||
|
||||
void FastWrite32(u32 value)
|
||||
{
|
||||
value = Common::swap32(value);
|
||||
std::memcpy(&m_gatherPipe[m_gatherPipeCount], &value, sizeof(u32));
|
||||
m_gatherPipeCount += sizeof(u32);
|
||||
std::memcpy(g_gather_pipe_ptr, &value, sizeof(u32));
|
||||
g_gather_pipe_ptr += sizeof(u32);
|
||||
}
|
||||
|
||||
void FastWrite64(u64 value)
|
||||
{
|
||||
value = Common::swap64(value);
|
||||
std::memcpy(&m_gatherPipe[m_gatherPipeCount], &value, sizeof(u64));
|
||||
m_gatherPipeCount += sizeof(u64);
|
||||
std::memcpy(g_gather_pipe_ptr, &value, sizeof(u64));
|
||||
g_gather_pipe_ptr += sizeof(u64);
|
||||
}
|
||||
|
||||
} // end of namespace GPFifo
|
||||
|
|
|
@ -15,11 +15,8 @@ enum
|
|||
GATHER_PIPE_SIZE = 32
|
||||
};
|
||||
|
||||
// More room for the fastmodes
|
||||
alignas(32) extern u8 m_gatherPipe[GATHER_PIPE_SIZE * 16];
|
||||
|
||||
// pipe counter
|
||||
extern u32 m_gatherPipeCount;
|
||||
// pipe pointer for JIT access
|
||||
extern u8* g_gather_pipe_ptr;
|
||||
|
||||
// Init
|
||||
void Init();
|
||||
|
|
|
@ -28,10 +28,12 @@ void CommonAsmRoutines::GenFifoWrite(int size)
|
|||
const void* start = GetCodePtr();
|
||||
|
||||
// Assume value in RSCRATCH
|
||||
MOV(32, R(RSCRATCH2), M(&GPFifo::m_gatherPipeCount));
|
||||
SwapAndStore(size, MDisp(RSCRATCH2, PtrOffset(GPFifo::m_gatherPipe)), RSCRATCH);
|
||||
ADD(32, R(RSCRATCH2), Imm8(size >> 3));
|
||||
MOV(32, M(&GPFifo::m_gatherPipeCount), R(RSCRATCH2));
|
||||
MOV(64, R(RSCRATCH2), ImmPtr(&GPFifo::g_gather_pipe_ptr));
|
||||
MOV(64, R(RSCRATCH2), MatR(RSCRATCH2));
|
||||
SwapAndStore(size, MatR(RSCRATCH2), RSCRATCH);
|
||||
MOV(64, R(RSCRATCH), ImmPtr(&GPFifo::g_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);
|
||||
|
|
|
@ -141,7 +141,7 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o
|
|||
void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s32 offset)
|
||||
{
|
||||
// We want to make sure to not get LR as a temp register
|
||||
gpr.Lock(W0, W1, W30);
|
||||
gpr.Lock(W0, W1);
|
||||
|
||||
ARM64Reg RS = gpr.R(value);
|
||||
|
||||
|
@ -242,41 +242,23 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
|
|||
if (accessSize != 8)
|
||||
WA = gpr.GetReg();
|
||||
|
||||
u64 base_ptr = std::min((u64)&GPFifo::m_gatherPipeCount, (u64)&GPFifo::m_gatherPipe);
|
||||
u32 count_off = (u64)&GPFifo::m_gatherPipeCount - base_ptr;
|
||||
u32 pipe_off = (u64)&GPFifo::m_gatherPipe - base_ptr;
|
||||
|
||||
MOVI2R(X30, base_ptr);
|
||||
|
||||
if (pipe_off)
|
||||
ADD(X1, X30, pipe_off);
|
||||
|
||||
LDR(INDEX_UNSIGNED, W0, X30, count_off);
|
||||
MOVP2R(X1, &GPFifo::g_gather_pipe_ptr);
|
||||
LDR(INDEX_UNSIGNED, X0, X1, 0);
|
||||
if (accessSize == 32)
|
||||
{
|
||||
REV32(WA, RS);
|
||||
if (pipe_off)
|
||||
STR(WA, X1, ArithOption(X0));
|
||||
else
|
||||
STR(WA, X30, ArithOption(X0));
|
||||
STR(INDEX_POST, WA, X0, 4);
|
||||
}
|
||||
else if (accessSize == 16)
|
||||
{
|
||||
REV16(WA, RS);
|
||||
if (pipe_off)
|
||||
STRH(WA, X1, ArithOption(X0));
|
||||
else
|
||||
STRH(WA, X30, ArithOption(X0));
|
||||
STRH(INDEX_POST, WA, X0, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pipe_off)
|
||||
STRB(RS, X1, ArithOption(X0));
|
||||
else
|
||||
STRB(RS, X30, ArithOption(X0));
|
||||
STRB(INDEX_POST, WA, X0, 1);
|
||||
}
|
||||
ADD(W0, W0, accessSize >> 3);
|
||||
STR(INDEX_UNSIGNED, W0, X30, count_off);
|
||||
STR(INDEX_UNSIGNED, X0, X1, 0);
|
||||
js.fifoBytesSinceCheck += accessSize >> 3;
|
||||
|
||||
if (accessSize != 8)
|
||||
|
@ -300,7 +282,7 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
|
|||
EmitBackpatchRoutine(flags, jo.fastmem, jo.fastmem, RS, XA, regs_in_use, fprs_in_use);
|
||||
}
|
||||
|
||||
gpr.Unlock(W0, W1, W30);
|
||||
gpr.Unlock(W0, W1);
|
||||
}
|
||||
|
||||
void JitArm64::lXX(UGeckoInstruction inst)
|
||||
|
|
|
@ -241,7 +241,7 @@ void JitArm64::stfXX(UGeckoInstruction inst)
|
|||
u32 imm_addr = 0;
|
||||
bool is_immediate = false;
|
||||
|
||||
gpr.Lock(W0, W1, W30);
|
||||
gpr.Lock(W0, W1);
|
||||
fpr.Lock(Q0);
|
||||
|
||||
bool single = (flags & BackPatchInfo::FLAG_SIZE_F32) && fpr.IsSingle(inst.FS, true);
|
||||
|
@ -357,16 +357,8 @@ void JitArm64::stfXX(UGeckoInstruction inst)
|
|||
else
|
||||
accessSize = 32;
|
||||
|
||||
u64 base_ptr = std::min((u64)&GPFifo::m_gatherPipeCount, (u64)&GPFifo::m_gatherPipe);
|
||||
u32 count_off = (u64)&GPFifo::m_gatherPipeCount - base_ptr;
|
||||
u32 pipe_off = (u64)&GPFifo::m_gatherPipe - base_ptr;
|
||||
|
||||
MOVI2R(X30, base_ptr);
|
||||
|
||||
if (pipe_off)
|
||||
ADD(X1, X30, pipe_off);
|
||||
|
||||
LDR(INDEX_UNSIGNED, W0, X30, count_off);
|
||||
MOVP2R(X1, &GPFifo::g_gather_pipe_ptr);
|
||||
LDR(INDEX_UNSIGNED, X0, X1, 0);
|
||||
if (flags & BackPatchInfo::FLAG_SIZE_F64)
|
||||
{
|
||||
m_float_emit.REV64(8, Q0, V0);
|
||||
|
@ -381,17 +373,9 @@ void JitArm64::stfXX(UGeckoInstruction inst)
|
|||
m_float_emit.REV32(8, D0, V0);
|
||||
}
|
||||
|
||||
if (pipe_off)
|
||||
{
|
||||
m_float_emit.STR(accessSize, accessSize == 64 ? Q0 : D0, X1, ArithOption(X0));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_float_emit.STR(accessSize, accessSize == 64 ? Q0 : D0, X30, ArithOption(X0));
|
||||
}
|
||||
m_float_emit.STR(accessSize, INDEX_POST, accessSize == 64 ? Q0 : D0, X0, accessSize >> 3);
|
||||
|
||||
ADD(W0, W0, accessSize >> 3);
|
||||
STR(INDEX_UNSIGNED, W0, X30, count_off);
|
||||
STR(INDEX_UNSIGNED, X0, X1, 0);
|
||||
js.fifoBytesSinceCheck += accessSize >> 3;
|
||||
|
||||
if (update)
|
||||
|
@ -414,6 +398,6 @@ void JitArm64::stfXX(UGeckoInstruction inst)
|
|||
{
|
||||
EmitBackpatchRoutine(flags, jo.fastmem, jo.fastmem, V0, XA, regs_in_use, fprs_in_use);
|
||||
}
|
||||
gpr.Unlock(W0, W1, W30);
|
||||
gpr.Unlock(W0, W1);
|
||||
fpr.Unlock(Q0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue