GPFifo: Use a pointer instead of an index

This simplifies code generated by the jits.
x86_64 jit now emits PIC.
This commit is contained in:
MerryMage 2017-04-13 23:31:29 +01:00
parent 722aca0830
commit c45028a708
5 changed files with 62 additions and 83 deletions

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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)

View File

@ -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);
}