mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-12-12 07:56:03 +00:00
Add a way to force alignment in JitSafeMem().
This commit is contained in:
parent
d2b874436d
commit
2d25d1eb05
@ -347,8 +347,8 @@ void Jit::Comp_SVQ(u32 op)
|
||||
}
|
||||
safe.Finish();
|
||||
|
||||
fpr.ReleaseSpillLocks();
|
||||
gpr.UnlockAll();
|
||||
fpr.ReleaseSpillLocks();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -469,8 +469,8 @@ bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset)
|
||||
return false;
|
||||
}
|
||||
|
||||
Jit::JitSafeMem::JitSafeMem(Jit *jit, int raddr, s32 offset)
|
||||
: jit_(jit), raddr_(raddr), offset_(offset), needsCheck_(false), needsSkip_(false)
|
||||
Jit::JitSafeMem::JitSafeMem(Jit *jit, int raddr, s32 offset, u32 alignMask)
|
||||
: jit_(jit), raddr_(raddr), offset_(offset), needsCheck_(false), needsSkip_(false), alignMask_(alignMask)
|
||||
{
|
||||
// This makes it more instructions, so let's play it safe and say we need a far jump.
|
||||
far_ = !g_Config.bIgnoreBadMemAccess || !CBreakPoints::GetMemChecks().empty();
|
||||
@ -497,9 +497,9 @@ bool Jit::JitSafeMem::PrepareWrite(OpArg &dest, int size)
|
||||
MemCheckImm(MEM_WRITE);
|
||||
|
||||
#ifdef _M_IX86
|
||||
dest = M(Memory::base + (iaddr_ & Memory::MEMVIEW32_MASK));
|
||||
dest = M(Memory::base + (iaddr_ & Memory::MEMVIEW32_MASK & alignMask_));
|
||||
#else
|
||||
dest = MDisp(RBX, iaddr_);
|
||||
dest = MDisp(RBX, iaddr_ & alignMask_);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@ -522,9 +522,9 @@ bool Jit::JitSafeMem::PrepareRead(OpArg &src, int size)
|
||||
MemCheckImm(MEM_READ);
|
||||
|
||||
#ifdef _M_IX86
|
||||
src = M(Memory::base + (iaddr_ & Memory::MEMVIEW32_MASK));
|
||||
src = M(Memory::base + (iaddr_ & Memory::MEMVIEW32_MASK & alignMask_));
|
||||
#else
|
||||
src = MDisp(RBX, iaddr_);
|
||||
src = MDisp(RBX, iaddr_ & alignMask_);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@ -540,7 +540,7 @@ OpArg Jit::JitSafeMem::NextFastAddress(int suboffset)
|
||||
{
|
||||
if (jit_->gpr.IsImmediate(raddr_))
|
||||
{
|
||||
u32 addr = jit_->gpr.GetImmediate32(raddr_) + offset_ + suboffset;
|
||||
u32 addr = (jit_->gpr.GetImmediate32(raddr_) + offset_ + suboffset) & alignMask_;
|
||||
|
||||
#ifdef _M_IX86
|
||||
return M(Memory::base + (addr & Memory::MEMVIEW32_MASK));
|
||||
@ -549,6 +549,8 @@ OpArg Jit::JitSafeMem::NextFastAddress(int suboffset)
|
||||
#endif
|
||||
}
|
||||
|
||||
_dbg_assert_msg_(HLE, (suboffset 0xFFFFFFFF) == suboffset, "suboffset must be aligned");
|
||||
|
||||
#ifdef _M_IX86
|
||||
return MDisp(xaddr_, (u32) Memory::base + offset_ + suboffset);
|
||||
#else
|
||||
@ -559,8 +561,13 @@ OpArg Jit::JitSafeMem::NextFastAddress(int suboffset)
|
||||
OpArg Jit::JitSafeMem::PrepareMemoryOpArg(ReadType type)
|
||||
{
|
||||
// We may not even need to move into EAX as a temporary.
|
||||
// TODO: Except on x86 in fastmem mode.
|
||||
if (jit_->gpr.R(raddr_).IsSimpleReg())
|
||||
bool needTemp = alignMask_ != 0xFFFFFFFF;
|
||||
#ifdef _M_IX86
|
||||
// We always mask on 32 bit in fast memory mode.
|
||||
needTemp = needTemp || g_Config.bFastMemory;
|
||||
#endif
|
||||
|
||||
if (jit_->gpr.R(raddr_).IsSimpleReg() && !needTemp)
|
||||
{
|
||||
jit_->gpr.BindToRegister(raddr_, true, false);
|
||||
xaddr_ = jit_->gpr.RX(raddr_);
|
||||
@ -587,18 +594,24 @@ OpArg Jit::JitSafeMem::PrepareMemoryOpArg(ReadType type)
|
||||
else
|
||||
{
|
||||
#ifdef _M_IX86
|
||||
// Need to modify it, too bad.
|
||||
if (xaddr_ != EAX)
|
||||
jit_->MOV(32, R(EAX), R(xaddr_));
|
||||
jit_->AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
|
||||
xaddr_ = EAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: This could be more optimal, but the common case is that we want xaddr_ not to include offset_.
|
||||
// Since we need to align them after add, we add and subtract.
|
||||
if (alignMask_ != 0xFFFFFFFF)
|
||||
{
|
||||
jit_->ADD(32, R(xaddr_), Imm32(offset_));
|
||||
jit_->AND(32, R(xaddr_), Imm32(alignMask_));
|
||||
jit_->SUB(32, R(xaddr_), Imm32(offset_));
|
||||
}
|
||||
|
||||
|
||||
#ifdef _M_IX86
|
||||
return MDisp(xaddr_, (u32) Memory::base + offset_);
|
||||
return MDisp(xaddr_, (u32) Memory::base + offset_);
|
||||
#else
|
||||
return MComplex(RBX, xaddr_, SCALE_1, offset_);
|
||||
return MComplex(RBX, xaddr_, SCALE_1, offset_);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -636,9 +649,13 @@ bool Jit::JitSafeMem::PrepareSlowWrite()
|
||||
void Jit::JitSafeMem::DoSlowWrite(void *safeFunc, const OpArg src, int suboffset)
|
||||
{
|
||||
if (iaddr_ != (u32) -1)
|
||||
jit_->MOV(32, R(EAX), Imm32(iaddr_ + suboffset));
|
||||
jit_->MOV(32, R(EAX), Imm32((iaddr_ + suboffset) & alignMask_));
|
||||
else
|
||||
{
|
||||
jit_->LEA(32, EAX, MDisp(xaddr_, offset_ + suboffset));
|
||||
if (alignMask_ != 0xFFFFFFFF)
|
||||
jit_->AND(32, R(EAX), Imm32(alignMask_));
|
||||
}
|
||||
|
||||
jit_->ABI_CallFunctionAA(jit_->thunks.ProtectFunction(safeFunc, 2), src, R(EAX));
|
||||
needsCheck_ = true;
|
||||
@ -653,12 +670,14 @@ bool Jit::JitSafeMem::PrepareSlowRead(void *safeFunc)
|
||||
// No slow read necessary.
|
||||
if (ImmValid())
|
||||
return false;
|
||||
jit_->MOV(32, R(EAX), Imm32(iaddr_));
|
||||
jit_->MOV(32, R(EAX), Imm32(iaddr_ & alignMask_));
|
||||
}
|
||||
else
|
||||
{
|
||||
PrepareSlowAccess();
|
||||
jit_->LEA(32, EAX, MDisp(xaddr_, offset_));
|
||||
if (alignMask_ != 0xFFFFFFFF)
|
||||
jit_->AND(32, R(EAX), Imm32(alignMask_));
|
||||
}
|
||||
|
||||
jit_->ABI_CallFunctionA(jit_->thunks.ProtectFunction(safeFunc, 1), R(EAX));
|
||||
@ -679,13 +698,17 @@ void Jit::JitSafeMem::NextSlowRead(void *safeFunc, int suboffset)
|
||||
|
||||
if (jit_->gpr.IsImmediate(raddr_))
|
||||
{
|
||||
_dbg_assert_msg_(JIT, !Memory::IsValidAddress(iaddr_ + suboffset), "NextSlowRead() for a valid immediate address?");
|
||||
_dbg_assert_msg_(JIT, !Memory::IsValidAddress(iaddr_ + suboffset), "NextSlowRead() for an invalid immediate address?");
|
||||
|
||||
jit_->MOV(32, R(EAX), Imm32(iaddr_ + suboffset));
|
||||
jit_->MOV(32, R(EAX), Imm32((iaddr_ + suboffset) & alignMask_));
|
||||
}
|
||||
// For GPR, if xaddr_ was the dest register, this will be wrong. Don't use in GPR.
|
||||
else
|
||||
{
|
||||
jit_->LEA(32, EAX, MDisp(xaddr_, offset_ + suboffset));
|
||||
if (alignMask_ != 0xFFFFFFFF)
|
||||
jit_->AND(32, R(EAX), Imm32(alignMask_));
|
||||
}
|
||||
|
||||
jit_->ABI_CallFunctionA(jit_->thunks.ProtectFunction(safeFunc, 1), R(EAX));
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ private:
|
||||
class JitSafeMem
|
||||
{
|
||||
public:
|
||||
JitSafeMem(Jit *jit, int raddr, s32 offset);
|
||||
JitSafeMem(Jit *jit, int raddr, s32 offset, u32 alignMask = 0xFFFFFFFF);
|
||||
|
||||
// Emit code necessary for a memory write, returns true if MOV to dest is needed.
|
||||
bool PrepareWrite(OpArg &dest, int size);
|
||||
@ -336,6 +336,7 @@ private:
|
||||
bool needsCheck_;
|
||||
bool needsSkip_;
|
||||
bool far_;
|
||||
u32 alignMask_;
|
||||
u32 iaddr_;
|
||||
X64Reg xaddr_;
|
||||
FixupBranch tooLow_, tooHigh_, skip_;
|
||||
|
Loading…
Reference in New Issue
Block a user