Browse Source

Use more conventional loop structure

It's easier to understand the instret handling in this scheme.
pull/2151/head
Andrew Waterman 5 months ago
parent
commit
adb9235abf
  1. 20
      riscv/execute.cc

20
riscv/execute.cc

@ -229,7 +229,7 @@ void processor_t::step(size_t n)
state.prv_changed = false;
state.v_changed = false;
#define advance_pc() \
#define advance_pc() { \
if (unlikely(invalid_pc(pc))) { \
switch (pc) { \
case PC_SERIALIZE_BEFORE: state.serialized = true; break; \
@ -237,11 +237,11 @@ void processor_t::step(size_t n)
default: abort(); \
} \
pc = state.pc; \
break; \
goto serialize; \
} else { \
state.pc = pc; \
instret++; \
}
}}
try
{
@ -302,26 +302,21 @@ void processor_t::step(size_t n)
else while (instret < n)
{
// Main simulation loop, fast path.
for (auto ic_entry = _mmu->access_icache(pc); ; ) {
for (auto ic_entry = _mmu->access_icache(pc); instret < n; instret++) {
auto fetch = ic_entry->data;
ic_entry = ic_entry->next;
auto new_pc = execute_insn_fast(this, pc, fetch);
if (unlikely(ic_entry->tag != new_pc)) {
ic_entry = &_mmu->icache[_mmu->icache_index(new_pc)];
_mmu->icache[_mmu->icache_index(pc)].next = ic_entry;
if (ic_entry->tag != new_pc) {
pc = new_pc;
advance_pc();
break;
}
_mmu->icache[_mmu->icache_index(pc)].next = ic_entry;
}
pc = ic_entry->tag;
if (unlikely(instret + 1 == n))
break;
instret++;
state.pc = pc;
state.pc = pc = ic_entry->tag;
}
advance_pc();
}
}
catch(trap_t& t)
@ -368,6 +363,7 @@ void processor_t::step(size_t n)
in_wfi = true;
}
serialize:
state.minstret->bump((state.mcountinhibit->read() & MCOUNTINHIBIT_IR) ? 0 : instret);
// Model a hart whose CPI is 1.

Loading…
Cancel
Save