Browse Source

Use more conventional loop structure

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

Loading…
Cancel
Save