i cannot figure it out istg

This commit is contained in:
2026-05-27 17:32:17 +02:00
parent 4d9cb49b73
commit 19d2f5f402
5 changed files with 465 additions and 448 deletions
+34 -36
View File
@@ -96,65 +96,63 @@ u32 Interpreter::Step() {
return 1;
}
u32 DivideAddr(u32 addr, u32 &offset) {
offset = (addr & (MAX_LINES_PER_BLOCK - 1)) / 4;
return addr / MAX_LINES_PER_BLOCK;
}
std::shared_ptr<CachedLine> CachedState::GetLine(u64 addr) {
const CachedLine &CachedState::GetLine(u64 addr) {
u32 offset;
u32 page = DivideAddr(addr, offset);
if (blocks[page])
return blocks[page]->lines[offset];
return nullptr;
return blocks[page].lines[offset];
}
void CachedState::InsertLine(u64 addr, std::shared_ptr<CachedLine> line) {
void CachedState::InsertLine(u64 addr, const CachedLine &line) {
u32 offset;
u32 page = DivideAddr(addr, offset);
if (!blocks[page])
blocks[page] = std::make_unique<CachedBlock>();
blocks[page]->lines[offset] = line;
blocks[page].lines[offset] = line;
}
void CachedState::EvictLine(u64 addr) {
u32 offset;
u32 page = DivideAddr(addr, offset);
if (blocks[page]) {
blocks[page]->lines[offset].reset();
blocks[page].reset();
}
blocks[page].lines[offset] = CachedLine();
}
u32 Interpreter::ExecuteCached() {
auto addr = regs.pc;
auto blockAddr = addr;
auto line = cachedState.GetLine(addr);
auto page = (addr >> 12) & 0xfffff;
auto offset = addr & 0xfff;
auto &blocks = cachedState.blocks;
if (line) {
for (u32 i = 0; i < line->len; i++) {
if (!MaybeAdvance())
return i + 1;
if (page >= blocks.size())
blocks.push_back();
Instruction instr = line->code[i];
DecodeExecute(instr);
if (page < blocks.size()) {
const auto &block = blocks[page];
if (blocks[page].len > 0) {
for (u32 i = 0; i < block.len; i++) {
if (!MaybeAdvance())
return i + 1;
// Branch likely with false condition, it wasn't taken so don't execute the delay slot
if (IsBranchLikely(instr) && !regs.delaySlot)
break;
Instruction instr = block.code[i];
DecodeExecute(instr);
// Branch likely with false condition, it wasn't taken so don't execute the delay slot
if (IsBranchLikely(instr) && !regs.delaySlot)
break;
}
if (block.cycles == 0)
Scheduler::GetInstance().SkipToNext();
return block.cycles;
}
if (line->cycles == 0)
Scheduler::GetInstance().SkipToNext();
return line->cycles;
}
std::array<Instruction, MAX_INSTRUCTION_PER_LINE> code;
if (line.code.size() > 0) {
}
std::vector<Instruction> code;
code.resize(MAX_INSTRUCTION_PER_LINE);
u32 i;
bool fetchDelaySlot = false;
@@ -180,7 +178,7 @@ u32 Interpreter::ExecuteCached() {
}
}
cachedState.InsertLine(blockAddr, std::make_shared<CachedLine>(code, i, i));
cachedState.InsertLine(blockAddr, {code, i, i});
return ExecuteCached();
}
+8 -19
View File
@@ -5,36 +5,26 @@
namespace n64 {
struct Core;
static constexpr u32 MAX_LINES_PER_BLOCK = 1 << 12;
static constexpr u32 MAX_INSTRUCTION_PER_LINE = MAX_LINES_PER_BLOCK >> 2;
static constexpr u32 MAX_INSTRUCTION_PER_BLOCK = 1 << 12;
struct CachedLine {
std::array<Instruction, MAX_INSTRUCTION_PER_LINE> code = {};
struct CachedBlock {
std::array<Instruction, MAX_INSTRUCTION_PER_BLOCK> code = {};
u32 cycles = 0;
u32 len = 0;
};
struct CachedBlock {
std::array<std::shared_ptr<CachedLine>, MAX_LINES_PER_BLOCK / 4> lines = {};
};
using CachedBlocks = std::vector<std::unique_ptr<CachedBlock>>;
struct CachedState {
CachedState() { blocks.resize((u64(std::numeric_limits<u32>::max()) + 1) / MAX_LINES_PER_BLOCK); }
CachedBlocks blocks = {};
CachedState() {}
std::vector<CachedBlock> blocks = {};
bool exception = false;
void Reset() {
for (auto &block : blocks) {
block.reset();
}
blocks = {};
exception = false;
}
std::shared_ptr<CachedLine> GetLine(u64);
void InsertLine(u64, std::shared_ptr<CachedLine>);
const CachedLine &GetLine(u64);
void InsertLine(u64, const CachedLine &);
void EvictLine(u64);
};
@@ -51,7 +41,6 @@ struct Interpreter final {
cachedState.Reset();
}
CachedState cachedState;
private: