mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-14 06:50:29 +02:00
ARM64: Fix joining of lwl/lwr and swl/swr. "implement" the cache instruction.
This commit is contained in:
1 parent
1575025b3d
commit
dc2f6a30fb
2 files changed
+89
-9
No files matched your search
@@ -393,6 +393,37 @@ namespace MIPSComp
|
||||
}
|
||||
|
||||
void ArmJit::Comp_Cache(MIPSOpcode op) {
|
||||
DISABLE;
|
||||
// int imm = (s16)(op & 0xFFFF);
|
||||
// int rs = _RS;
|
||||
// int addr = R(rs) + imm;
|
||||
int func = (op >> 16) & 0x1F;
|
||||
|
||||
// It appears that a cache line is 0x40 (64) bytes, loops in games
|
||||
// issue the cache instruction at that interval.
|
||||
|
||||
// These codes might be PSP-specific, they don't match regular MIPS cache codes very well
|
||||
switch (func) {
|
||||
// Icache
|
||||
case 8:
|
||||
// Invalidate the instruction cache at this address
|
||||
DISABLE;
|
||||
break;
|
||||
// Dcache
|
||||
case 24:
|
||||
// "Create Dirty Exclusive" - for avoiding a cacheline fill before writing to it.
|
||||
// Will cause garbage on the real machine so we just ignore it, the app will overwrite the cacheline.
|
||||
break;
|
||||
case 25: // Hit Invalidate - zaps the line if present in cache. Should not writeback???? scary.
|
||||
// No need to do anything.
|
||||
break;
|
||||
case 27: // D-cube. Hit Writeback Invalidate. Tony Hawk Underground 2
|
||||
break;
|
||||
case 30: // GTA LCS, a lot. Fill (prefetch). Tony Hawk Underground 2
|
||||
break;
|
||||
|
||||
default:
|
||||
DISABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,15 +132,12 @@ namespace MIPSComp {
|
||||
MIPSGPReg rs = _RS;
|
||||
int o = op >> 26;
|
||||
|
||||
DISABLE;
|
||||
// TODO: For some reason I can't get this to work on ARM64.
|
||||
if (!js.inDelaySlot && false) {
|
||||
if (!js.inDelaySlot) {
|
||||
// Optimisation: Combine to single unaligned load/store
|
||||
bool isLeft = (o == 34 || o == 42);
|
||||
MIPSOpcode nextOp = GetOffsetInstruction(1);
|
||||
// Find a matching shift in opposite direction with opposite offset.
|
||||
if (nextOp == (isLeft ? (op.encoding + (4 << 26) - 3)
|
||||
: (op.encoding - (4 << 26) + 3))) {
|
||||
if (nextOp == (isLeft ? (op.encoding + (4 << 26) - 3) : (op.encoding - (4 << 26) + 3))) {
|
||||
EatInstruction(nextOp);
|
||||
nextOp = MIPSOpcode(((load ? 35 : 43) << 26) | ((isLeft ? nextOp : op) & 0x03FFFFFF)); //lw, sw
|
||||
Comp_ITypeMem(nextOp);
|
||||
@@ -148,6 +145,8 @@ namespace MIPSComp {
|
||||
}
|
||||
}
|
||||
|
||||
DISABLE;
|
||||
|
||||
u32 iaddr = gpr.IsImm(rs) ? offset + gpr.GetImm(rs) : 0xFFFFFFFF;
|
||||
std::vector<FixupBranch> skips;
|
||||
|
||||
@@ -313,6 +312,25 @@ namespace MIPSComp {
|
||||
std::vector<FixupBranch> skips;
|
||||
ARM64Reg addrReg = SCRATCH1;
|
||||
|
||||
int dataSize = 4;
|
||||
switch (o) {
|
||||
case 37:
|
||||
case 33:
|
||||
dataSize = 2;
|
||||
break;
|
||||
case 36:
|
||||
case 32:
|
||||
dataSize = 1;
|
||||
break;
|
||||
// Store
|
||||
case 41:
|
||||
dataSize = 2;
|
||||
break;
|
||||
case 40:
|
||||
dataSize = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (o) {
|
||||
case 32: //lb
|
||||
case 33: //lh
|
||||
@@ -328,8 +346,8 @@ namespace MIPSComp {
|
||||
int offsetRange = 0x3ff;
|
||||
if (o == 41 || o == 33 || o == 37 || o == 32)
|
||||
offsetRange = 0xff; // 8 bit offset only
|
||||
|
||||
if (!gpr.IsImm(rs) && rs != rt && (offset <= offsetRange) && offset >= 0) {
|
||||
if (!gpr.IsImm(rs) && rs != rt && (offset <= offsetRange) && offset >= 0 &&
|
||||
(dataSize == 1 || (offset & (dataSize - 1)) == 0)) { // Check that the offset is aligned to the access size as that's required for INDEX_UNSIGNED encodings. we can get here through fallback from lwl/lwr
|
||||
gpr.SpillLock(rs, rt);
|
||||
gpr.MapRegAsPointer(rs);
|
||||
gpr.MapReg(rt, load ? MAP_NOINIT : 0);
|
||||
@@ -408,6 +426,37 @@ namespace MIPSComp {
|
||||
}
|
||||
|
||||
void Arm64Jit::Comp_Cache(MIPSOpcode op) {
|
||||
DISABLE;
|
||||
// int imm = (s16)(op & 0xFFFF);
|
||||
// int rs = _RS;
|
||||
// int addr = R(rs) + imm;
|
||||
int func = (op >> 16) & 0x1F;
|
||||
|
||||
// It appears that a cache line is 0x40 (64) bytes, loops in games
|
||||
// issue the cache instruction at that interval.
|
||||
|
||||
// These codes might be PSP-specific, they don't match regular MIPS cache codes very well
|
||||
switch (func) {
|
||||
// Icache
|
||||
case 8:
|
||||
// Invalidate the instruction cache at this address
|
||||
DISABLE;
|
||||
break;
|
||||
// Dcache
|
||||
case 24:
|
||||
// "Create Dirty Exclusive" - for avoiding a cacheline fill before writing to it.
|
||||
// Will cause garbage on the real machine so we just ignore it, the app will overwrite the cacheline.
|
||||
break;
|
||||
case 25: // Hit Invalidate - zaps the line if present in cache. Should not writeback???? scary.
|
||||
// No need to do anything.
|
||||
break;
|
||||
case 27: // D-cube. Hit Writeback Invalidate. Tony Hawk Underground 2
|
||||
break;
|
||||
case 30: // GTA LCS, a lot. Fill (prefetch). Tony Hawk Underground 2
|
||||
break;
|
||||
|
||||
default:
|
||||
DISABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user