make idle loop detection a little more specific with where the load goes
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include <Core.hpp>
|
||||
#include <Scheduler.hpp>
|
||||
#include <mem/Utils.hpp>
|
||||
|
||||
namespace n64 {
|
||||
Interpreter::Interpreter(Mem &mem, Registers ®s) : regs(regs), mem(mem) {}
|
||||
@@ -118,11 +119,18 @@ bool Interpreter::DetectIdleLoop(const std::array<Instruction, MAX_INSTR_PER_BLO
|
||||
// _andi reg2, reg1, immediate
|
||||
|
||||
auto branch = code[lastInstructionIndex - 1];
|
||||
auto load = code[lastInstructionIndex - 2]; // load
|
||||
auto load = code[lastInstructionIndex - 2];
|
||||
bool isLoad = load.opcode() == Instruction::LW || load.opcode() == Instruction::LWU;
|
||||
if (isLoad) {
|
||||
const s16 offset = load;
|
||||
const u64 address = regs.Read<s64>(load.rs()) + offset;
|
||||
u32 paddr;
|
||||
if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr))
|
||||
panic("Failed to translate load address in DetectIdleLoop");
|
||||
|
||||
return (load.opcode() == Instruction::LW || load.opcode() == Instruction::LWU) &&
|
||||
delay.opcode() == Instruction::ANDI && branch.IsBranch() && branch.offset() == -8 &&
|
||||
load.rt() == delay.rs() && delay.rt() == branch.rs();
|
||||
return isLoad && delay.opcode() == Instruction::ANDI && branch.IsBranch() && branch.offset() == -8 &&
|
||||
load.rt() == delay.rs() && delay.rt() == branch.rs() && IsAddressMMIOorRDRAM(paddr);
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 4) {
|
||||
@@ -132,12 +140,19 @@ bool Interpreter::DetectIdleLoop(const std::array<Instruction, MAX_INSTR_PER_BLO
|
||||
// _nop
|
||||
|
||||
auto branch = code[lastInstructionIndex - 1];
|
||||
auto andi = code[lastInstructionIndex - 2]; // andi
|
||||
auto load = code[lastInstructionIndex - 3]; // load
|
||||
auto andi = code[lastInstructionIndex - 2];
|
||||
auto load = code[lastInstructionIndex - 3];
|
||||
const s16 offset = load;
|
||||
const u64 address = regs.Read<s64>(load.rs()) + offset;
|
||||
bool isLoad = load.opcode() == Instruction::LW || load.opcode() == Instruction::LWU;
|
||||
if (isLoad) {
|
||||
u32 paddr;
|
||||
if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr))
|
||||
panic("Failed to translate load address in DetectIdleLoop");
|
||||
|
||||
return (load.opcode() == Instruction::LW || load.opcode() == Instruction::LWU) &&
|
||||
andi.opcode() == Instruction::ANDI && branch.IsBranch() && branch.offset() == -12 &&
|
||||
load.rt() == andi.rs() && andi.rt() == branch.rs();
|
||||
return isLoad && andi.opcode() == Instruction::ANDI && branch.IsBranch() && branch.offset() == -12 &&
|
||||
load.rt() == andi.rs() && andi.rt() == branch.rs() && IsAddressMMIOorRDRAM(paddr);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <ircolib/mem_access.hpp>
|
||||
#include <MemoryRegions.hpp>
|
||||
|
||||
namespace n64 {
|
||||
static bool IsAddressMMIOorRDRAM(u32 addr) {
|
||||
if (ircolib::IsInsideRange(addr, RDRAM_REGION_START, RDRAM_REGION_END))
|
||||
return true;
|
||||
|
||||
if (ircolib::IsInsideRange(addr, MMIO_REGION_START_1, MMIO_REGION_END_1) ||
|
||||
ircolib::IsInsideRange(addr, MMIO_REGION_START_2, MMIO_REGION_END_2))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace n64
|
||||
@@ -4,12 +4,13 @@
|
||||
int main(const int argc, char **argv) {
|
||||
KaizenGui kaizenGui;
|
||||
cflags::cflags flags;
|
||||
flags.add_string_callback('\0', "rom", [&kaizenGui](const std::string& v) { kaizenGui.LoadROM(v); }, "Rom to launch from command-line");
|
||||
flags.add_string_callback('\0', "movie", [](const std::string& v) { KaizenGui::LoadTAS(v); }, "Mupen Movie to replay");
|
||||
flags.add_string_callback(
|
||||
'\0', "rom", [&kaizenGui](const std::string &v) { kaizenGui.LoadROM(v); }, "Rom to launch from command-line");
|
||||
flags.add_string_callback(
|
||||
'\0', "movie", [](const std::string &v) { KaizenGui::LoadTAS(v); }, "Mupen Movie to replay");
|
||||
|
||||
if(!flags.parse(argc, argv)) {
|
||||
if (!flags.parse(argc, argv))
|
||||
return -1;
|
||||
}
|
||||
|
||||
kaizenGui.run();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user