mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 07:20:49 +00:00
Minor code formatting in x86 Jit
This commit is contained in:
parent
3ceb0a8540
commit
c1f9f96621
@ -48,20 +48,8 @@ namespace MIPSComp
|
||||
{
|
||||
using namespace Gen;
|
||||
|
||||
#ifdef _M_IX86
|
||||
|
||||
#define SAVE_FLAGS PUSHF();
|
||||
#define LOAD_FLAGS POPF();
|
||||
|
||||
#elif defined(_M_X64)
|
||||
|
||||
static u64 saved_flags;
|
||||
|
||||
#define SAVE_FLAGS {PUSHF(); POP(64, R(EAX)); MOV(64, M(&saved_flags), R(EAX));}
|
||||
#define LOAD_FLAGS {MOV(64, R(EAX), M(&saved_flags)); PUSH(64, R(EAX)); POPF();}
|
||||
|
||||
#endif
|
||||
|
||||
const bool USE_JIT_MISSMAP = false;
|
||||
static std::map<std::string, u32> notJitOps;
|
||||
|
||||
@ -138,8 +126,7 @@ Jit::Jit(MIPSState *mips)
|
||||
Jit::~Jit() {
|
||||
}
|
||||
|
||||
void Jit::DoState(PointerWrap &p)
|
||||
{
|
||||
void Jit::DoState(PointerWrap &p) {
|
||||
auto s = p.Section("Jit", 1, 2);
|
||||
if (!s)
|
||||
return;
|
||||
@ -158,8 +145,7 @@ void Jit::DoState(PointerWrap &p)
|
||||
}
|
||||
|
||||
// This is here so the savestate matches between jit and non-jit.
|
||||
void Jit::DoDummyState(PointerWrap &p)
|
||||
{
|
||||
void Jit::DoDummyState(PointerWrap &p) {
|
||||
auto s = p.Section("Jit", 1, 2);
|
||||
if (!s)
|
||||
return;
|
||||
@ -173,49 +159,41 @@ void Jit::DoDummyState(PointerWrap &p)
|
||||
}
|
||||
|
||||
|
||||
void Jit::GetStateAndFlushAll(RegCacheState &state)
|
||||
{
|
||||
void Jit::GetStateAndFlushAll(RegCacheState &state) {
|
||||
gpr.GetState(state.gpr);
|
||||
fpr.GetState(state.fpr);
|
||||
FlushAll();
|
||||
}
|
||||
|
||||
void Jit::RestoreState(const RegCacheState& state)
|
||||
{
|
||||
void Jit::RestoreState(const RegCacheState& state) {
|
||||
gpr.RestoreState(state.gpr);
|
||||
fpr.RestoreState(state.fpr);
|
||||
}
|
||||
|
||||
void Jit::FlushAll()
|
||||
{
|
||||
void Jit::FlushAll() {
|
||||
gpr.Flush();
|
||||
fpr.Flush();
|
||||
FlushPrefixV();
|
||||
}
|
||||
|
||||
void Jit::FlushPrefixV()
|
||||
{
|
||||
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
void Jit::FlushPrefixV() {
|
||||
if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0) {
|
||||
MOV(32, M(&mips_->vfpuCtrl[VFPU_CTRL_SPREFIX]), Imm32(js.prefixS));
|
||||
js.prefixSFlag = (JitState::PrefixState) (js.prefixSFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
|
||||
if ((js.prefixTFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
if ((js.prefixTFlag & JitState::PREFIX_DIRTY) != 0) {
|
||||
MOV(32, M(&mips_->vfpuCtrl[VFPU_CTRL_TPREFIX]), Imm32(js.prefixT));
|
||||
js.prefixTFlag = (JitState::PrefixState) (js.prefixTFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
|
||||
if ((js.prefixDFlag & JitState::PREFIX_DIRTY) != 0)
|
||||
{
|
||||
if ((js.prefixDFlag & JitState::PREFIX_DIRTY) != 0) {
|
||||
MOV(32, M(&mips_->vfpuCtrl[VFPU_CTRL_DPREFIX]), Imm32(js.prefixD));
|
||||
js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::WriteDowncount(int offset)
|
||||
{
|
||||
void Jit::WriteDowncount(int offset) {
|
||||
const int downcount = js.downcountAmount + offset;
|
||||
SUB(32, M(&mips_->downcount), downcount > 127 ? Imm32(downcount) : Imm8(downcount));
|
||||
}
|
||||
@ -245,32 +223,46 @@ void Jit::ClearCache()
|
||||
GenerateFixedCode(jo);
|
||||
}
|
||||
|
||||
void Jit::CompileDelaySlot(int flags, RegCacheState *state)
|
||||
{
|
||||
void Jit::SaveFlags() {
|
||||
PUSHF();
|
||||
#if defined(_M_X64)
|
||||
// On X64, the above misaligns the stack. However there might be a cheaper solution than this.
|
||||
POP(64, R(EAX));
|
||||
MOV(64, M(&saved_flags), R(EAX));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Jit::LoadFlags() {
|
||||
#if defined(_M_X64)
|
||||
MOV(64, R(EAX), M(&saved_flags));
|
||||
PUSH(64, R(EAX));
|
||||
#endif
|
||||
POPF();
|
||||
}
|
||||
|
||||
void Jit::CompileDelaySlot(int flags, RegCacheState *state) {
|
||||
// Need to offset the downcount which was already incremented for the branch + delay slot.
|
||||
CheckJitBreakpoint(GetCompilerPC() + 4, -2);
|
||||
|
||||
if (flags & DELAYSLOT_SAFE)
|
||||
SAVE_FLAGS; // preserve flag around the delay slot!
|
||||
SaveFlags(); // preserve flag around the delay slot!
|
||||
|
||||
js.inDelaySlot = true;
|
||||
MIPSOpcode op = GetOffsetInstruction(1);
|
||||
MIPSCompileOp(op, this);
|
||||
js.inDelaySlot = false;
|
||||
|
||||
if (flags & DELAYSLOT_FLUSH)
|
||||
{
|
||||
if (flags & DELAYSLOT_FLUSH) {
|
||||
if (state != NULL)
|
||||
GetStateAndFlushAll(*state);
|
||||
else
|
||||
FlushAll();
|
||||
}
|
||||
if (flags & DELAYSLOT_SAFE)
|
||||
LOAD_FLAGS; // restore flag!
|
||||
LoadFlags(); // restore flag!
|
||||
}
|
||||
|
||||
void Jit::EatInstruction(MIPSOpcode op)
|
||||
{
|
||||
void Jit::EatInstruction(MIPSOpcode op) {
|
||||
MIPSInfo info = MIPSGetInfo(op);
|
||||
if (info & DELAYSLOT) {
|
||||
ERROR_LOG_REPORT_ONCE(ateDelaySlot, JIT, "Ate a branch op.");
|
||||
@ -285,8 +277,7 @@ void Jit::EatInstruction(MIPSOpcode op)
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(op);
|
||||
}
|
||||
|
||||
void Jit::Compile(u32 em_address)
|
||||
{
|
||||
void Jit::Compile(u32 em_address) {
|
||||
PROFILE_THIS_SCOPE("jitc");
|
||||
if (GetSpaceLeft() < 0x10000 || blocks.IsFull()) {
|
||||
ClearCache();
|
||||
@ -327,8 +318,7 @@ void Jit::Compile(u32 em_address)
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::RunLoopUntil(u64 globalticks)
|
||||
{
|
||||
void Jit::RunLoopUntil(u64 globalticks) {
|
||||
PROFILE_THIS_SCOPE("jit");
|
||||
((void (*)())enterDispatcher)();
|
||||
}
|
||||
@ -569,8 +559,7 @@ bool Jit::ReplaceJalTo(u32 dest) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Jit::Comp_ReplacementFunc(MIPSOpcode op)
|
||||
{
|
||||
void Jit::Comp_ReplacementFunc(MIPSOpcode op) {
|
||||
// We get here if we execute the first instruction of a replaced function. This means
|
||||
// that we do need to return to RA.
|
||||
|
||||
@ -646,8 +635,7 @@ void Jit::Comp_ReplacementFunc(MIPSOpcode op)
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::Comp_Generic(MIPSOpcode op)
|
||||
{
|
||||
void Jit::Comp_Generic(MIPSOpcode op) {
|
||||
FlushAll();
|
||||
MIPSInterpretFunc func = MIPSGetInterpretFunc(op);
|
||||
_dbg_assert_msg_(JIT, (MIPSGetInfo(op) & DELAYSLOT) == 0, "Cannot use interpreter for branch ops.");
|
||||
@ -675,16 +663,14 @@ void Jit::Comp_Generic(MIPSOpcode op)
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::WriteExit(u32 destination, int exit_num)
|
||||
{
|
||||
void Jit::WriteExit(u32 destination, int exit_num) {
|
||||
_dbg_assert_msg_(JIT, exit_num < MAX_JIT_BLOCK_EXITS, "Expected a valid exit_num");
|
||||
|
||||
if (!Memory::IsValidAddress(destination)) {
|
||||
ERROR_LOG_REPORT(JIT, "Trying to write block exit to illegal destination %08x: pc = %08x", destination, currentMIPS->pc);
|
||||
}
|
||||
// If we need to verify coreState and rewind, we may not jump yet.
|
||||
if (js.afterOp & (JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE))
|
||||
{
|
||||
if (js.afterOp & (JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE)) {
|
||||
// CORE_RUNNING is <= CORE_NEXTFRAME.
|
||||
CMP(32, M(&coreState), Imm32(CORE_NEXTFRAME));
|
||||
FixupBranch skipCheck = J_CC(CC_LE);
|
||||
@ -721,8 +707,7 @@ void Jit::WriteExit(u32 destination, int exit_num)
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::WriteExitDestInReg(X64Reg reg)
|
||||
{
|
||||
void Jit::WriteExitDestInReg(X64Reg reg) {
|
||||
// If we need to verify coreState and rewind, we may not jump yet.
|
||||
if (js.afterOp & (JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE))
|
||||
{
|
||||
@ -738,8 +723,7 @@ void Jit::WriteExitDestInReg(X64Reg reg)
|
||||
WriteDowncount();
|
||||
|
||||
// Validate the jump to avoid a crash?
|
||||
if (!g_Config.bFastMemory)
|
||||
{
|
||||
if (!g_Config.bFastMemory) {
|
||||
CMP(32, R(reg), Imm32(PSP_GetKernelMemoryBase()));
|
||||
FixupBranch tooLow = J_CC(CC_B);
|
||||
CMP(32, R(reg), Imm32(PSP_GetUserMemoryEnd()));
|
||||
@ -757,8 +741,7 @@ void Jit::WriteExitDestInReg(X64Reg reg)
|
||||
ABI_CallFunctionA((const void *)&Memory::GetPointer, R(reg));
|
||||
|
||||
// If we're ignoring, coreState didn't trip - so trip it now.
|
||||
if (g_Config.bIgnoreBadMemAccess)
|
||||
{
|
||||
if (g_Config.bIgnoreBadMemAccess) {
|
||||
CMP(32, R(EAX), Imm32(0));
|
||||
FixupBranch skip = J_CC(CC_NE);
|
||||
ABI_CallFunctionA((const void *)&Core_UpdateState, Imm32(CORE_ERROR));
|
||||
@ -767,18 +750,15 @@ void Jit::WriteExitDestInReg(X64Reg reg)
|
||||
|
||||
SUB(32, M(&mips_->downcount), Imm8(0));
|
||||
JMP(dispatcherCheckCoreState, true);
|
||||
}
|
||||
else if (reg == EAX)
|
||||
{
|
||||
} else if (reg == EAX) {
|
||||
J_CC(CC_NS, dispatcherInEAXNoCheck, true);
|
||||
JMP(dispatcher, true);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
JMP(dispatcher, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::WriteSyscallExit()
|
||||
{
|
||||
void Jit::WriteSyscallExit() {
|
||||
WriteDowncount();
|
||||
if (js.afterOp & JitState::AFTER_MEMCHECK_CLEANUP) {
|
||||
RestoreRoundingMode();
|
||||
@ -788,11 +768,9 @@ void Jit::WriteSyscallExit()
|
||||
JMP(dispatcherCheckCoreState, true);
|
||||
}
|
||||
|
||||
bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset)
|
||||
{
|
||||
if (CBreakPoints::IsAddressBreakPoint(addr))
|
||||
{
|
||||
SAVE_FLAGS;
|
||||
bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset) {
|
||||
if (CBreakPoints::IsAddressBreakPoint(addr)) {
|
||||
SaveFlags();
|
||||
FlushAll();
|
||||
MOV(32, M(&mips_->pc), Imm32(GetCompilerPC()));
|
||||
RestoreRoundingMode();
|
||||
@ -804,41 +782,36 @@ bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset)
|
||||
WriteDowncount(downcountOffset);
|
||||
ApplyRoundingMode();
|
||||
// Just to fix the stack.
|
||||
LOAD_FLAGS;
|
||||
LoadFlags();
|
||||
JMP(dispatcherCheckCoreState, true);
|
||||
SetJumpTarget(skip);
|
||||
|
||||
ApplyRoundingMode();
|
||||
LOAD_FLAGS;
|
||||
|
||||
LoadFlags();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1)
|
||||
{
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1) {
|
||||
// We don't regcache RCX, so the below is safe (and also faster, maybe branch prediction?)
|
||||
ABI_CallFunctionA(thunks.ProtectFunction(func, 1), arg1);
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1, const OpArg &arg2)
|
||||
{
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1, const OpArg &arg2) {
|
||||
// We don't regcache RCX/RDX, so the below is safe (and also faster, maybe branch prediction?)
|
||||
ABI_CallFunctionAA(thunks.ProtectFunction(func, 2), arg1, arg2);
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(const void *func, const u32 arg1, const u32 arg2, const u32 arg3)
|
||||
{
|
||||
void Jit::CallProtectedFunction(const void *func, const u32 arg1, const u32 arg2, const u32 arg3) {
|
||||
// On x64, we need to save R8, which is caller saved.
|
||||
thunks.Enter(this);
|
||||
ABI_CallFunctionCCC(func, arg1, arg2, arg3);
|
||||
thunks.Leave(this);
|
||||
}
|
||||
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1, const u32 arg2, const u32 arg3)
|
||||
{
|
||||
void Jit::CallProtectedFunction(const void *func, const OpArg &arg1, const u32 arg2, const u32 arg3) {
|
||||
// On x64, we need to save R8, which is caller saved.
|
||||
thunks.Enter(this);
|
||||
ABI_CallFunctionACC(func, arg1, arg2, arg3);
|
||||
|
@ -15,6 +15,9 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
|
||||
// TODO: Implement https://github.com/dolphin-emu/dolphin/pull/1025/commits/b597ec3e081a289d9ac782586617a876535183d6 .
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
@ -36,7 +39,6 @@ namespace MIPSComp {
|
||||
// This is called when Jit hits a breakpoint. Returns 1 when hit.
|
||||
u32 JitBreakpoint();
|
||||
|
||||
// TODO: Hmm, humongous.
|
||||
struct RegCacheState {
|
||||
GPRRegCacheState gpr;
|
||||
FPURegCacheState fpr;
|
||||
@ -292,6 +294,8 @@ private:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void SaveFlags();
|
||||
void LoadFlags();
|
||||
|
||||
JitBlockCache blocks;
|
||||
JitOptions jo;
|
||||
|
Loading…
Reference in New Issue
Block a user