From c45028a7081f872e87c9d9b42f70f3086aa912f7 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Thu, 13 Apr 2017 23:31:29 +0100 Subject: [PATCH] GPFifo: Use a pointer instead of an index This simplifies code generated by the jits. x86_64 jit now emits PIC. --- Source/Core/Core/HW/GPFifo.cpp | 66 +++++++++++-------- Source/Core/Core/HW/GPFifo.h | 7 +- .../PowerPC/Jit64Common/Jit64AsmCommon.cpp | 10 +-- .../PowerPC/JitArm64/JitArm64_LoadStore.cpp | 34 +++------- .../JitArm64/JitArm64_LoadStoreFloating.cpp | 28 ++------ 5 files changed, 62 insertions(+), 83 deletions(-) diff --git a/Source/Core/Core/HW/GPFifo.cpp b/Source/Core/Core/HW/GPFifo.cpp index febd1bd3c7..174a284f11 100644 --- a/Source/Core/Core/HW/GPFifo.cpp +++ b/Source/Core/Core/HW/GPFifo.cpp @@ -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(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 diff --git a/Source/Core/Core/HW/GPFifo.h b/Source/Core/Core/HW/GPFifo.h index 73c95e8c75..eb37c589b9 100644 --- a/Source/Core/Core/HW/GPFifo.h +++ b/Source/Core/Core/HW/GPFifo.h @@ -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(); diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp index 9180be67f4..d5b1652a5a 100644 --- a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp +++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp @@ -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); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index 8e8bb6cf6b..71a7048228 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -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) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp index c869bd61a9..c616b8dfd0 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp @@ -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); }