i cannot figure it out istg
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user