|
|
|
@ -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.
|
|
|
|
|