mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-23 04:46:26 +02:00
Merge pull request #7826 from unknownbrackets/arm64-safemem
arm64: Add a safemem path
This commit is contained in:
@@ -86,7 +86,7 @@ void Arm64Jit::Comp_FPULS(MIPSOpcode op)
|
||||
MIPSGPReg rs = _RS;
|
||||
// u32 addr = R(rs) + offset;
|
||||
// logBlocks = 1;
|
||||
bool doCheck = false;
|
||||
std::vector<FixupBranch> skips;
|
||||
switch (op >> 26) {
|
||||
case 49: //FI(ft) = Memory::Read_U32(addr); break; //lwc1
|
||||
if (!gpr.IsImm(rs) && jo.cachePointers && g_Config.bFastMemory && (offset & 3) == 0 && offset <= 16380 && offset >= 0) {
|
||||
@@ -106,17 +106,12 @@ void Arm64Jit::Comp_FPULS(MIPSOpcode op)
|
||||
if (g_Config.bFastMemory) {
|
||||
SetScratch1ToEffectiveAddress(rs, offset);
|
||||
} else {
|
||||
SetCCAndSCRATCH1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
doCheck = true;
|
||||
skips = SetScratch1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
}
|
||||
MOVK(SCRATCH1_64, ((uint64_t)Memory::base) >> 32, SHIFT_32);
|
||||
}
|
||||
FixupBranch skip;
|
||||
if (doCheck) {
|
||||
skip = B(CC_EQ);
|
||||
}
|
||||
LDR(INDEX_UNSIGNED, fpr.R(ft), SCRATCH1_64, 0);
|
||||
if (doCheck) {
|
||||
for (auto skip : skips) {
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
fpr.ReleaseSpillLocksAndDiscardTemps();
|
||||
@@ -139,18 +134,13 @@ void Arm64Jit::Comp_FPULS(MIPSOpcode op)
|
||||
if (g_Config.bFastMemory) {
|
||||
SetScratch1ToEffectiveAddress(rs, offset);
|
||||
} else {
|
||||
SetCCAndSCRATCH1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
doCheck = true;
|
||||
skips = SetScratch1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
}
|
||||
MOVK(SCRATCH1_64, ((uint64_t)Memory::base) >> 32, SHIFT_32);
|
||||
}
|
||||
FixupBranch skip2;
|
||||
if (doCheck) {
|
||||
skip2 = B(CC_EQ);
|
||||
}
|
||||
STR(INDEX_UNSIGNED, fpr.R(ft), SCRATCH1_64, 0);
|
||||
if (doCheck) {
|
||||
SetJumpTarget(skip2);
|
||||
for (auto skip : skips) {
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -78,9 +78,52 @@ namespace MIPSComp
|
||||
}
|
||||
}
|
||||
|
||||
void Arm64Jit::SetCCAndSCRATCH1ForSafeAddress(MIPSGPReg rs, s16 offset, ARM64Reg tempReg, bool reverse) {
|
||||
std::vector<FixupBranch> Arm64Jit::SetScratch1ForSafeAddress(MIPSGPReg rs, s16 offset, ARM64Reg tempReg) {
|
||||
std::vector<FixupBranch> skips;
|
||||
|
||||
SetScratch1ToEffectiveAddress(rs, offset);
|
||||
// TODO
|
||||
|
||||
// We can do this a little smarter by shifting out the lower 8 bits, since blocks are 0x100 aligned.
|
||||
// PSP_GetUserMemoryEnd() is dynamic, but the others encode to imms just fine.
|
||||
// So we only need to safety check the one value.
|
||||
|
||||
if ((PSP_GetUserMemoryEnd() & 0x000FFFFF) == 0) {
|
||||
// In other words, shift right 8.
|
||||
UBFX(tempReg, SCRATCH1, 8, 24);
|
||||
// Now check if we're higher than that.
|
||||
CMPI2R(tempReg, PSP_GetUserMemoryEnd() >> 8);
|
||||
} else {
|
||||
// Compare first using the tempReg, then shift into it.
|
||||
CMPI2R(SCRATCH1, PSP_GetUserMemoryEnd(), tempReg);
|
||||
UBFX(tempReg, SCRATCH1, 8, 24);
|
||||
}
|
||||
skips.push_back(B(CC_HS));
|
||||
|
||||
// If its higher than memory start and we didn't skip yet, it must be good. Hurray.
|
||||
CMPI2R(tempReg, PSP_GetKernelMemoryBase() >> 8);
|
||||
FixupBranch inRAM = B(CC_HS);
|
||||
|
||||
// If we got here and it's higher, then it's between VRAM and RAM - skip.
|
||||
CMPI2R(tempReg, PSP_GetVidMemEnd() >> 8);
|
||||
skips.push_back(B(CC_HS));
|
||||
|
||||
// And if it's higher the VRAM and we're still here again, it's in VRAM.
|
||||
CMPI2R(tempReg, PSP_GetVidMemBase() >> 8);
|
||||
FixupBranch inVRAM = B(CC_HS);
|
||||
|
||||
// Last gap, this is between SRAM and VRAM. Skip it.
|
||||
CMPI2R(tempReg, PSP_GetScratchpadMemoryEnd() >> 8);
|
||||
skips.push_back(B(CC_HS));
|
||||
|
||||
// And for lower than SRAM, we just skip again.
|
||||
CMPI2R(tempReg, PSP_GetScratchpadMemoryBase() >> 8);
|
||||
skips.push_back(B(CC_LO));
|
||||
|
||||
// At this point, we're either in SRAM (above) or in RAM/VRAM.
|
||||
SetJumpTarget(inRAM);
|
||||
SetJumpTarget(inVRAM);
|
||||
|
||||
return skips;
|
||||
}
|
||||
|
||||
void Arm64Jit::Comp_ITypeMemLR(MIPSOpcode op, bool load) {
|
||||
@@ -107,8 +150,7 @@ namespace MIPSComp
|
||||
}
|
||||
|
||||
u32 iaddr = gpr.IsImm(rs) ? offset + gpr.GetImm(rs) : 0xFFFFFFFF;
|
||||
bool doCheck = false;
|
||||
FixupBranch skip;
|
||||
std::vector<FixupBranch> skips;
|
||||
|
||||
if (gpr.IsImm(rs) && Memory::IsValidAddress(iaddr)) {
|
||||
u32 addr = iaddr;
|
||||
@@ -173,14 +215,10 @@ namespace MIPSComp
|
||||
}
|
||||
|
||||
if (false && !g_Config.bFastMemory && rs != MIPS_REG_SP) {
|
||||
SetCCAndSCRATCH1ForSafeAddress(rs, offset, SCRATCH2, true);
|
||||
doCheck = true;
|
||||
skips = SetScratch1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
} else {
|
||||
SetScratch1ToEffectiveAddress(rs, offset);
|
||||
}
|
||||
if (doCheck) {
|
||||
skip = B();
|
||||
}
|
||||
|
||||
// Need temp regs. TODO: Get from the regcache?
|
||||
static const ARM64Reg LR_SCRATCH3 = W9;
|
||||
@@ -254,7 +292,7 @@ namespace MIPSComp
|
||||
POP2(EncodeRegTo64(LR_SCRATCH3), EncodeRegTo64(LR_SCRATCH4));
|
||||
}
|
||||
|
||||
if (doCheck) {
|
||||
for (auto skip : skips) {
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
}
|
||||
@@ -273,7 +311,7 @@ namespace MIPSComp
|
||||
}
|
||||
|
||||
u32 iaddr = gpr.IsImm(rs) ? offset + gpr.GetImm(rs) : 0xFFFFFFFF;
|
||||
bool doCheck = false;
|
||||
std::vector<FixupBranch> skips;
|
||||
ARM64Reg addrReg = SCRATCH1;
|
||||
|
||||
switch (o) {
|
||||
@@ -333,8 +371,7 @@ namespace MIPSComp
|
||||
load ? gpr.MapDirtyIn(rt, rs) : gpr.MapInIn(rt, rs);
|
||||
|
||||
if (!g_Config.bFastMemory && rs != MIPS_REG_SP) {
|
||||
SetCCAndSCRATCH1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
doCheck = true;
|
||||
skips = SetScratch1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
} else {
|
||||
SetScratch1ToEffectiveAddress(rs, offset);
|
||||
}
|
||||
@@ -353,14 +390,10 @@ namespace MIPSComp
|
||||
case 41: STRH(gpr.R(rt), MEMBASEREG, addrReg); break;
|
||||
case 40: STRB(gpr.R(rt), MEMBASEREG, addrReg); break;
|
||||
}
|
||||
/*
|
||||
if (doCheck) {
|
||||
if (load) {
|
||||
SetCC(CC_EQ);
|
||||
MOVI2R(gpr.R(rt), 0);
|
||||
}
|
||||
SetCC(CC_AL);
|
||||
}*/
|
||||
for (auto skip : skips) {
|
||||
SetJumpTarget(skip);
|
||||
// TODO: Could clear to zero here on load, if skipping this for good reads.
|
||||
}
|
||||
break;
|
||||
case 34: //lwl
|
||||
case 38: //lwr
|
||||
|
||||
@@ -205,7 +205,7 @@ namespace MIPSComp
|
||||
int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5);
|
||||
MIPSGPReg rs = _RS;
|
||||
|
||||
bool doCheck = false;
|
||||
std::vector<FixupBranch> skips;
|
||||
switch (op >> 26) {
|
||||
case 50: //lv.s // VI(vt) = Memory::Read_U32(addr);
|
||||
{
|
||||
@@ -226,18 +226,13 @@ namespace MIPSComp
|
||||
if (g_Config.bFastMemory) {
|
||||
SetScratch1ToEffectiveAddress(rs, offset);
|
||||
} else {
|
||||
SetCCAndSCRATCH1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
doCheck = true;
|
||||
skips = SetScratch1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
}
|
||||
// Pointerify
|
||||
MOVK(SCRATCH1_64, ((uint64_t)Memory::base) >> 32, SHIFT_32);
|
||||
}
|
||||
FixupBranch skip;
|
||||
if (doCheck) {
|
||||
skip = B(CC_EQ);
|
||||
}
|
||||
fp.LDR(32, INDEX_UNSIGNED, fpr.V(vt), SCRATCH1_64, 0);
|
||||
if (doCheck) {
|
||||
for (auto skip : skips) {
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
}
|
||||
@@ -262,17 +257,12 @@ namespace MIPSComp
|
||||
if (g_Config.bFastMemory) {
|
||||
SetScratch1ToEffectiveAddress(rs, offset);
|
||||
} else {
|
||||
SetCCAndSCRATCH1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
doCheck = true;
|
||||
skips = SetScratch1ForSafeAddress(rs, offset, SCRATCH2);
|
||||
}
|
||||
MOVK(SCRATCH1_64, ((uint64_t)Memory::base) >> 32, SHIFT_32);
|
||||
}
|
||||
FixupBranch skip;
|
||||
if (doCheck) {
|
||||
skip = B(CC_EQ);
|
||||
}
|
||||
fp.STR(32, INDEX_UNSIGNED, fpr.V(vt), SCRATCH1_64, 0);
|
||||
if (doCheck) {
|
||||
for (auto skip : skips) {
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
}
|
||||
@@ -291,7 +281,7 @@ namespace MIPSComp
|
||||
int vt = (((op >> 16) & 0x1f)) | ((op&1) << 5);
|
||||
MIPSGPReg rs = _RS;
|
||||
|
||||
bool doCheck = false;
|
||||
std::vector<FixupBranch> skips;
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 54: //lv.q
|
||||
@@ -309,22 +299,16 @@ namespace MIPSComp
|
||||
if (g_Config.bFastMemory) {
|
||||
SetScratch1ToEffectiveAddress(rs, imm);
|
||||
} else {
|
||||
SetCCAndSCRATCH1ForSafeAddress(rs, imm, SCRATCH2);
|
||||
doCheck = true;
|
||||
skips = SetScratch1ForSafeAddress(rs, imm, SCRATCH2);
|
||||
}
|
||||
MOVK(SCRATCH1_64, ((uint64_t)Memory::base) >> 32, SHIFT_32);
|
||||
}
|
||||
|
||||
FixupBranch skip;
|
||||
if (doCheck) {
|
||||
skip = B(CC_EQ);
|
||||
}
|
||||
|
||||
// Removed consecutive opt for now
|
||||
for (int i = 0; i < 4; i++)
|
||||
fp.LDR(32, INDEX_UNSIGNED, fpr.V(vregs[i]), SCRATCH1_64, i * 4);
|
||||
|
||||
if (doCheck) {
|
||||
for (auto skip : skips) {
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
}
|
||||
@@ -345,21 +329,15 @@ namespace MIPSComp
|
||||
if (g_Config.bFastMemory) {
|
||||
SetScratch1ToEffectiveAddress(rs, imm);
|
||||
} else {
|
||||
SetCCAndSCRATCH1ForSafeAddress(rs, imm, SCRATCH2);
|
||||
doCheck = true;
|
||||
skips = SetScratch1ForSafeAddress(rs, imm, SCRATCH2);
|
||||
}
|
||||
MOVK(SCRATCH1_64, ((uint64_t)Memory::base) >> 32, SHIFT_32);
|
||||
}
|
||||
|
||||
FixupBranch skip;
|
||||
if (doCheck) {
|
||||
skip = B(CC_EQ);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
fp.STR(32, INDEX_UNSIGNED, fpr.V(vregs[i]), SCRATCH1_64, i * 4);
|
||||
|
||||
if (doCheck) {
|
||||
for (auto skip : skips) {
|
||||
SetJumpTarget(skip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ private:
|
||||
|
||||
// Utils
|
||||
void SetScratch1ToEffectiveAddress(MIPSGPReg rs, s16 offset);
|
||||
void SetCCAndSCRATCH1ForSafeAddress(MIPSGPReg rs, s16 offset, Arm64Gen::ARM64Reg tempReg, bool reverse = false);
|
||||
std::vector<Arm64Gen::FixupBranch> SetScratch1ForSafeAddress(MIPSGPReg rs, s16 offset, Arm64Gen::ARM64Reg tempReg);
|
||||
void Comp_ITypeMemLR(MIPSOpcode op, bool load);
|
||||
|
||||
JitBlockCache blocks;
|
||||
|
||||
Reference in New Issue
Block a user