ARM64: Fix joining of lwl/lwr and swl/swr. "implement" the cache instruction.

This commit is contained in:
Henrik Rydgard committed 2015-07-11 16:25:22 +02:00
1 parent 1575025b3d
commit dc2f6a30fb
2 files changed
+89 -9

No files matched your search

+32 -1
View File
@@ -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;
}
}
}
+57 -8
View File
@@ -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;
}
}
}