attempting more serious idle skipping
This commit is contained in:
@@ -120,8 +120,7 @@ void Core::Run(const float volumeL, const float volumeR) {
|
||||
const u32 taken = StepCPU();
|
||||
cycles += taken;
|
||||
frameCycles += taken;
|
||||
if (cpuType == Interpreted) // because i will call it inside instead, when it's not the interpreter
|
||||
StepRSP(taken);
|
||||
StepRSP(taken);
|
||||
Scheduler::GetInstance().Tick(taken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,6 @@ u32 Interpreter::ExecuteCached() {
|
||||
// 0, making so the emulator halts cause the outer loop won't advance
|
||||
const auto blockCycles = line->cycles;
|
||||
for (u32 i = 0; i < line->len; i++) {
|
||||
Core::GetInstance().StepRSP(1);
|
||||
if (!MaybeAdvance())
|
||||
return i + 1;
|
||||
|
||||
@@ -167,11 +166,13 @@ u32 Interpreter::ExecuteCached() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (blockCycles == 0) {
|
||||
panic("Cycles are 0!");
|
||||
if (line->idleSkip) {
|
||||
Scheduler::GetInstance().SkipToNext();
|
||||
}
|
||||
|
||||
if (blockCycles == 0)
|
||||
panic("Cycles are 0");
|
||||
|
||||
return blockCycles;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,11 @@ static constexpr u32 MAX_INSTR_PER_BLOCK = 128;
|
||||
#define CACHE_GET_LINE(addr) ((addr & ((cachedState.MAX_LINES) - 1)) >> 2)
|
||||
|
||||
struct CachedLine {
|
||||
bool idleSkip = false;
|
||||
std::array<Instruction, MAX_INSTR_PER_BLOCK> code = {};
|
||||
u32 len = 0;
|
||||
u32 cycles = 0;
|
||||
} __attribute__((__packed__));
|
||||
};
|
||||
|
||||
template <u32 lineAmount>
|
||||
struct CachedBlock {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <Core.hpp>
|
||||
#include <Scheduler.hpp>
|
||||
|
||||
#define check_signed_overflow(op1, op2, res) (((~((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1)
|
||||
#define check_signed_underflow(op1, op2, res) (((((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1)
|
||||
@@ -144,12 +145,13 @@ void Interpreter::branch(const bool cond, const s64 address) {
|
||||
}
|
||||
|
||||
void Interpreter::branch_likely(const bool cond, const s64 address) {
|
||||
if (cond) {
|
||||
regs.delaySlot = true;
|
||||
regs.nextPC = address;
|
||||
} else {
|
||||
if (!cond) {
|
||||
regs.SetPC64(regs.nextPC);
|
||||
return;
|
||||
}
|
||||
|
||||
regs.delaySlot = true;
|
||||
regs.nextPC = address;
|
||||
}
|
||||
|
||||
void Interpreter::b(const Instruction instr, const bool cond) {
|
||||
|
||||
@@ -113,6 +113,33 @@ static bool IsBranchLikely(const Instruction instr) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsBranch(const Instruction instr) {
|
||||
switch (instr.opcode()) {
|
||||
case Instruction::BEQ:
|
||||
case Instruction::BNE:
|
||||
case Instruction::BLEZ:
|
||||
case Instruction::BGTZ:
|
||||
return true;
|
||||
case Instruction::REGIMM:
|
||||
switch (instr.regimm()) {
|
||||
case Instruction::BLTZ:
|
||||
case Instruction::BGEZ:
|
||||
case Instruction::BLTZAL:
|
||||
case Instruction::BGEZAL:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case Instruction::COP1:
|
||||
if (instr.cop_rs() == 8 && (instr.cop_rt() == 0 || instr.cop_rt() == 1))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define ARG1 rcx
|
||||
#define ARG2 rdx
|
||||
|
||||
Reference in New Issue
Block a user