it's a start...
This commit is contained in:
@@ -88,6 +88,9 @@ void Core::StepRSP(const u32 cpuCycles) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cpuType == CachedInterpreter)
|
||||||
|
return mmio.rsp.ExecuteCached();
|
||||||
|
|
||||||
static constexpr u32 cpuRatio = 3, rspRatio = 2;
|
static constexpr u32 cpuRatio = 3, rspRatio = 2;
|
||||||
|
|
||||||
regs.steps += cpuCycles;
|
regs.steps += cpuCycles;
|
||||||
|
|||||||
@@ -152,8 +152,6 @@ u32 Interpreter::ExecuteCached() {
|
|||||||
// 0, making so the emulator halts cause the outer loop won't advance
|
// 0, making so the emulator halts cause the outer loop won't advance
|
||||||
const auto blockCycles = line->cycles;
|
const auto blockCycles = line->cycles;
|
||||||
for (u32 i = 0; i < line->len; i++) {
|
for (u32 i = 0; i < line->len; i++) {
|
||||||
addr += 4;
|
|
||||||
|
|
||||||
if (!MaybeAdvance())
|
if (!MaybeAdvance())
|
||||||
return i + 1;
|
return i + 1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
#include <log.hpp>
|
#include <log.hpp>
|
||||||
|
#include <jit/helpers.hpp>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
RSP::RSP() { Reset(); }
|
RSP::RSP() { Reset(); }
|
||||||
@@ -230,4 +231,70 @@ void RSP::Write(const u32 addr, const u32 val) {
|
|||||||
panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, val);
|
panic("Unimplemented SP register write {:08X}, val: {:08X}", addr, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RSP::CacheBlock(u16 addr) {
|
||||||
|
auto blockAddr = addr;
|
||||||
|
|
||||||
|
CachedLine line;
|
||||||
|
u32 i;
|
||||||
|
bool fetchDelaySlot = false;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_INSTR_PER_BLOCK; i++) {
|
||||||
|
Instruction instr = ircolib::ReadAccess<u32>(imem, addr & IMEM_DSIZE);
|
||||||
|
|
||||||
|
addr += 4;
|
||||||
|
line.code[i] = instr;
|
||||||
|
|
||||||
|
if (fetchDelaySlot) {
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InstrEndsBlock(instr)) {
|
||||||
|
if (InstrHasDelaySlot(instr) && !fetchDelaySlot) {
|
||||||
|
fetchDelaySlot = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
i = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line.cycles = i;
|
||||||
|
line.len = i;
|
||||||
|
cachedState.blocks[CACHE_GET_BLOCK(blockAddr)]->lines[CACHE_GET_LINE(blockAddr)] = new CachedLine(line);
|
||||||
|
|
||||||
|
return ExecuteCached();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RSP::ExecuteCached() {
|
||||||
|
u16 addr = pc;
|
||||||
|
auto &blocks = cachedState.blocks;
|
||||||
|
if (!blocks[CACHE_GET_BLOCK(addr)]) {
|
||||||
|
blocks[CACHE_GET_BLOCK(addr)] = new CachedBlock<cachedState.MAX_LINES / 4>();
|
||||||
|
return CacheBlock(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto line = blocks[CACHE_GET_BLOCK(addr)]->lines[CACHE_GET_LINE(addr)];
|
||||||
|
if (line) {
|
||||||
|
for (u32 i = 0; i < line->len; i++) {
|
||||||
|
prevDelaySlot = delaySlot;
|
||||||
|
delaySlot = false;
|
||||||
|
|
||||||
|
oldPC = pc & 0xFFC;
|
||||||
|
pc = nextPC & 0xFFC;
|
||||||
|
nextPC += 4;
|
||||||
|
|
||||||
|
Instruction instr = line->code[i];
|
||||||
|
Exec(instr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CacheBlock(addr);
|
||||||
|
}
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <core/RDP.hpp>
|
#include <core/RDP.hpp>
|
||||||
#include <core/mmio/MI.hpp>
|
#include <core/mmio/MI.hpp>
|
||||||
#include <Instruction.hpp>
|
#include <Instruction.hpp>
|
||||||
|
#include <JITUtils.hpp>
|
||||||
|
|
||||||
#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF])
|
#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF])
|
||||||
#define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1))
|
#define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1))
|
||||||
@@ -145,10 +146,18 @@ struct RSP {
|
|||||||
VPR l{}, h{};
|
VPR l{}, h{};
|
||||||
} vcc, vco;
|
} vcc, vco;
|
||||||
|
|
||||||
|
CachedState<4, 0xFFF> cachedState;
|
||||||
|
bool delaySlot = false, prevDelaySlot = false;
|
||||||
|
|
||||||
RSP();
|
RSP();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
|
void ExecuteCached();
|
||||||
|
void CacheBlock(u16 addr);
|
||||||
|
|
||||||
FORCE_INLINE void Step() {
|
FORCE_INLINE void Step() {
|
||||||
|
prevDelaySlot = delaySlot;
|
||||||
|
delaySlot = false;
|
||||||
gpr[0] = 0;
|
gpr[0] = 0;
|
||||||
const u32 instr = ircolib::ReadAccess<u32>(imem, pc & IMEM_DSIZE);
|
const u32 instr = ircolib::ReadAccess<u32>(imem, pc & IMEM_DSIZE);
|
||||||
oldPC = pc & 0xFFC;
|
oldPC = pc & 0xFFC;
|
||||||
@@ -380,15 +389,7 @@ private:
|
|||||||
FORCE_INLINE void branch(const u16 address, const bool cond) {
|
FORCE_INLINE void branch(const u16 address, const bool cond) {
|
||||||
if (cond) {
|
if (cond) {
|
||||||
nextPC = address & 0xFFC;
|
nextPC = address & 0xFFC;
|
||||||
}
|
delaySlot = true;
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE void branch_likely(const u16 address, const bool cond) {
|
|
||||||
if (cond) {
|
|
||||||
nextPC = address & 0xFFC;
|
|
||||||
} else {
|
|
||||||
pc = nextPC & 0xFFC;
|
|
||||||
nextPC = pc + 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user