| 383 | |
| 384 | extern int Dcache; |
| 385 | void CACHE() |
| 386 | { |
| 387 | u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; |
| 388 | // CACHE_LOG("cpuRegs.GPR.r[_Rs_].UL[0] = %x, IMM = %x RT = %x", cpuRegs.GPR.r[_Rs_].UL[0], _Imm_, _Rt_); |
| 389 | |
| 390 | switch (_Rt_) |
| 391 | { |
| 392 | case 0x1a: //DHIN (Data Cache Hit Invalidate) |
| 393 | doCacheHitOp(addr, "DHIN", [](CacheLine line) { |
| 394 | line.clear(); |
| 395 | }); |
| 396 | break; |
| 397 | |
| 398 | case 0x18: //DHWBIN (Data Cache Hit WriteBack with Invalidate) |
| 399 | doCacheHitOp(addr, "DHWBIN", [](CacheLine line) { |
| 400 | line.writeBackIfNeeded(); |
| 401 | line.clear(); |
| 402 | }); |
| 403 | break; |
| 404 | |
| 405 | case 0x1c: //DHWOIN (Data Cache Hit WriteBack Without Invalidate) |
| 406 | doCacheHitOp(addr, "DHWOIN", [](CacheLine line) { |
| 407 | line.writeBackIfNeeded(); |
| 408 | }); |
| 409 | break; |
| 410 | |
| 411 | case 0x16: //DXIN (Data Cache Index Invalidate) |
| 412 | { |
| 413 | const int index = cache.setIdxFor(addr); |
| 414 | const int way = addr & 0x1; |
| 415 | CacheLine line = cache.lineAt(index, way); |
| 416 | |
| 417 | CACHE_LOG("CACHE DXIN addr %x, index %d, way %d, flag %x", addr, index, way, line.tag.flags()); |
| 418 | |
| 419 | line.clear(); |
| 420 | break; |
| 421 | } |
| 422 | |
| 423 | case 0x11: //DXLDT (Data Cache Load Data into TagLo) |
| 424 | { |
| 425 | const int index = cache.setIdxFor(addr); |
| 426 | const int way = addr & 0x1; |
| 427 | CacheLine line = cache.lineAt(index, way); |
| 428 | |
| 429 | cpuRegs.CP0.n.TagLo = *reinterpret_cast<u32*>(&line.data.bytes[addr & 0x3C]); |
| 430 | |
| 431 | CACHE_LOG("CACHE DXLDT addr %x, index %d, way %d, DATA %x OP %x", addr, index, way, cpuRegs.CP0.n.TagLo, cpuRegs.code); |
| 432 | break; |
| 433 | } |
| 434 | |
| 435 | case 0x10: //DXLTG (Data Cache Load Tag into TagLo) |
| 436 | { |
| 437 | const int index = (addr >> 6) & 0x3F; |
| 438 | const int way = addr & 0x1; |
| 439 | CacheLine line = cache.lineAt(index, way); |
| 440 | |
| 441 | // DXLTG demands that SYNC.L is called before this command, which forces the cache to write back, so presumably games are checking the cache has updated the memory |
| 442 | // For speed, we will do it here. |
nothing calls this directly
no test coverage detected