aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/decode.h19
-rw-r--r--riscv/mmu.h17
-rw-r--r--riscv/processor.cc14
-rw-r--r--riscv/processor.h3
-rw-r--r--riscv/sim.h1
5 files changed, 35 insertions, 19 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 6dfe6b9..2078e58 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -143,30 +143,29 @@ union insn_t
uint32_t bits;
};
-#if 0
#include <stdio.h>
-class trace_writeback
+class do_writeback
{
public:
- trace_writeback(reg_t* _rf, int _rd) : rf(_rf), rd(_rd) {}
+ do_writeback(reg_t* _rf, int _rd) : rf(_rf), rd(_rd) {}
- reg_t operator = (reg_t rhs)
+ const do_writeback& operator = (reg_t rhs)
{
+#if 0
printf("R[%x] <= %llx\n",rd,(long long)rhs);
+#endif
rf[rd] = rhs;
- return rhs;
+ rf[0] = 0;
+ return *this;
}
+ operator reg_t() { return rf[rd]; }
+
private:
reg_t* rf;
int rd;
};
-#define do_writeback(rf,rd) trace_writeback(rf,rd)
-#else
-#define do_writeback(rf,rd) rf[rd]
-#endif
-
#define throw_illegal_instruction \
({ if (utmode) throw trap_vector_illegal_instruction; \
else throw trap_illegal_instruction; })
diff --git a/riscv/mmu.h b/riscv/mmu.h
index ef54079..e25e90a 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -5,6 +5,7 @@
#include "trap.h"
#include "icsim.h"
#include "common.h"
+#include "processor.h"
class processor_t;
@@ -68,7 +69,8 @@ public:
*(type##_t*)paddr = val; \
}
- insn_t __attribute__((always_inline)) load_insn(reg_t addr, bool rvc)
+ insn_t __attribute__((always_inline)) load_insn(reg_t addr, bool rvc,
+ insn_func_t* func)
{
insn_t insn;
@@ -78,6 +80,9 @@ public:
void* addr_lo = translate(addr, false, true);
insn.bits = *(uint16_t*)addr_lo;
+ *func = processor_t::dispatch_table
+ [insn.bits % processor_t::DISPATCH_TABLE_SIZE];
+
if(!INSN_IS_RVC(insn.bits))
{
void* addr_hi = translate(addr+2, false, true);
@@ -88,9 +93,10 @@ public:
#endif
{
reg_t idx = (addr/sizeof(insn_t)) % ICACHE_ENTRIES;
- bool hit = icache_tag[idx] == addr;
- if(likely(hit))
- return icache_data[idx];
+ insn_t data = icache_data[idx];
+ *func = icache_func[idx];
+ if(likely(icache_tag[idx] == addr))
+ return data;
// the processor guarantees alignment based upon rvc mode
void* paddr = translate(addr, false, true);
@@ -98,6 +104,8 @@ public:
icache_tag[idx] = addr;
icache_data[idx] = insn;
+ icache_func[idx] = *func = processor_t::dispatch_table
+ [insn.bits % processor_t::DISPATCH_TABLE_SIZE];
}
#ifdef RISCV_ENABLE_ICSIM
@@ -157,6 +165,7 @@ private:
static const reg_t ICACHE_ENTRIES = 256;
insn_t icache_data[ICACHE_ENTRIES];
+ insn_func_t icache_func[ICACHE_ENTRIES];
reg_t icache_tag[ICACHE_ENTRIES];
icsim_t* icsim;
diff --git a/riscv/processor.cc b/riscv/processor.cc
index bb09eb5..e86536e 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -172,11 +172,17 @@ void processor_t::step(size_t n, bool noisy)
{
take_interrupt();
+ mmu_t& _mmu = mmu;
+ insn_t insn;
+ insn_func_t func;
+ reg_t npc = pc;
#define execute_insn(noisy) \
- do { insn_t insn = mmu.load_insn(pc, sr & SR_EC); \
- if(noisy) disasm(insn,pc); \
- pc = dispatch_table[insn.bits % DISPATCH_TABLE_SIZE](this, insn, pc); \
- XPR[0] = 0; } while(0)
+ do { \
+ insn = _mmu.load_insn(npc, sr & SR_EC, &func); \
+ if(noisy) disasm(insn,pc); \
+ npc = func(this, insn, npc); \
+ pc = npc; \
+ } while(0)
if(noisy) for( ; i < n; i++)
execute_insn(true);
diff --git a/riscv/processor.h b/riscv/processor.h
index b21663a..8b2d2bc 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -4,12 +4,12 @@
#include "decode.h"
#include <cstring>
#include "trap.h"
-#include "mmu.h"
#include "icsim.h"
#define MAX_UTS 2048
class processor_t;
+class mmu_t;
typedef reg_t (*insn_func_t)(processor_t*, insn_t, reg_t);
class sim_t;
@@ -89,6 +89,7 @@ private:
icsim_t* dtlbsim;
friend class sim_t;
+ friend class mmu_t;
#include "dispatch.h"
};
diff --git a/riscv/sim.h b/riscv/sim.h
index c56ad95..ab388b8 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -4,6 +4,7 @@
#include <vector>
#include <string>
#include "processor.h"
+#include "mmu.h"
class appserver_link_t;