diff options
author | Andrew Waterman <waterman@eecs.berkeley.edu> | 2014-02-13 18:46:42 -0800 |
---|---|---|
committer | Andrew Waterman <waterman@eecs.berkeley.edu> | 2014-02-13 18:46:42 -0800 |
commit | 6c99f30d7848ab3b5f59a07ae5027cc4ec0c1322 (patch) | |
tree | 990b2db9c499bd7cbc6425a9a6347400b98e9fee /riscv | |
parent | b227ec194fdea025724ec541c0b472708e439bbe (diff) | |
download | riscv-isa-sim-6c99f30d7848ab3b5f59a07ae5027cc4ec0c1322.zip riscv-isa-sim-6c99f30d7848ab3b5f59a07ae5027cc4ec0c1322.tar.gz riscv-isa-sim-6c99f30d7848ab3b5f59a07ae5027cc4ec0c1322.tar.bz2 |
Fix I$ simulator not making forward progress
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/mmu.h | 10 | ||||
-rw-r--r-- | riscv/processor.cc | 28 |
2 files changed, 17 insertions, 21 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h index c09cfc4..c3d8f41 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -78,11 +78,11 @@ public: store_func(uint64) // load instruction from memory at aligned address. - inline icache_entry_t access_icache(reg_t addr) + inline icache_entry_t* access_icache(reg_t addr) { reg_t idx = (addr / sizeof(insn_t)) % ICACHE_SIZE; - icache_entry_t entry = icache[idx]; - if (likely(entry.tag == addr)) + icache_entry_t* entry = &icache[idx]; + if (likely(entry->tag == addr)) return entry; void* iaddr = translate(addr, sizeof(insn_t), false, true); @@ -99,12 +99,12 @@ public: icache[idx].tag = -1; tracer.trace(paddr, sizeof(insn_t), false, true); } - return icache[idx]; + return &icache[idx]; } inline insn_fetch_t load_insn(reg_t addr) { - return access_icache(addr).data; + return access_icache(addr)->data; } void set_processor(processor_t* p) { proc = p; flush_tlb(); } diff --git a/riscv/processor.cc b/riscv/processor.cc index 83bfbec..e931c6b 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -130,31 +130,27 @@ void processor_t::step(size_t n) else while (n > 0) { size_t idx = (state.pc / sizeof(insn_t)) % ICACHE_SIZE; - auto ic_entry_init = &_mmu->icache[idx], ic_entry = ic_entry_init; - - #define update_count() { \ - size_t i = ic_entry - ic_entry_init; \ - state.count += i; \ - if (i >= n) break; \ - n -= i; } + auto ic_entry = _mmu->access_icache(state.pc), ic_entry_init = ic_entry; #define ICACHE_ACCESS(idx) { \ insn_t insn = ic_entry->data.insn.insn; \ insn_func_t func = ic_entry->data.func; \ - if (unlikely(ic_entry->tag != state.pc)) break; \ - ic_entry++; \ commit_log(&state, insn); \ - state.pc = func(this, insn, state.pc); } + ic_entry++; \ + state.pc = func(this, insn, state.pc); \ + if (idx < ICACHE_SIZE-1 && unlikely(ic_entry->tag != state.pc)) break; \ + } - switch (idx) while (true) + switch (idx) { - ICACHE_SWITCH; - update_count(); - ic_entry_init = ic_entry = &_mmu->icache[0]; + ICACHE_SWITCH; // auto-generated into icache.h } - _mmu->access_icache(state.pc); - update_count(); + size_t i = ic_entry - ic_entry_init; + state.count += i; + if (i >= n) + break; + n -= i; } } catch(trap_t& t) |