};
// load instruction from memory at aligned address.
- // (needed because instruction alignment requirement is variable
- // if RVC is supported)
- // returns the instruction at the specified address, given the current
- // RVC mode. func is set to a pointer to a function that knows how to
- // execute the returned instruction.
- inline insn_fetch_t load_insn(reg_t addr, bool rvc)
+ inline insn_fetch_t load_insn(reg_t addr)
{
- #ifdef RISCV_ENABLE_RVC
- if(addr % 4 == 2 && rvc) // fetch across word boundary
+#ifdef RISCV_ENABLE_RVC
+# error TODO: Make MMU instruction cache support 2-byte alignment
+#endif
+ reg_t idx = (addr/sizeof(insn_t::itype)) % ICACHE_ENTRIES;
+ if (unlikely(icache_tag[idx] != addr))
{
- reg_t addr_lo = translate(addr, 2, false, true);
+ reg_t paddr = translate(addr, sizeof(insn_t::itype), false, true);
insn_fetch_t fetch;
- fetch.insn.bits = *(uint16_t*)(mem + addr_lo);
+ fetch.insn.itype = *(decltype(insn_t::itype)*)(mem + paddr);
fetch.func = proc->decode_insn(fetch.insn);
- if(!INSN_IS_RVC(fetch.insn.bits))
- {
- reg_t addr_hi = translate(addr+2, 2, false, true);
- fetch.insn.bits |= (uint32_t)*(uint16_t*)(mem + addr_hi) << 16;
- }
- return fetch;
- }
- else
- #endif
- {
- reg_t idx = (addr/sizeof(insn_t::itype)) % ICACHE_ENTRIES;
- insn_fetch_t fetch;
- if (unlikely(icache_tag[idx] != addr))
+ reg_t idx = (paddr/sizeof(insn_t::itype)) % ICACHE_ENTRIES;
+ icache_tag[idx] = addr;
+ icache_data[idx] = fetch;
+
+ if (tracer.interested_in_range(paddr, paddr + sizeof(insn_t::itype), false, true))
{
- reg_t paddr = translate(addr, sizeof(insn_t::itype), false, true);
- fetch.insn.itype = *(decltype(insn_t::itype)*)(mem + paddr);
- fetch.func = proc->decode_insn(fetch.insn);
-
- reg_t idx = (paddr/sizeof(insn_t::itype)) % ICACHE_ENTRIES;
- icache_tag[idx] = addr;
- icache_data[idx] = fetch.insn;
- icache_func[idx] = fetch.func;
-
- if (tracer.interested_in_range(paddr, paddr + sizeof(insn_t::itype), false, true))
- {
- icache_tag[idx] = -1;
- tracer.trace(paddr, sizeof(insn_t::itype), false, true);
- }
+ icache_tag[idx] = -1;
+ tracer.trace(paddr, sizeof(insn_t::itype), false, true);
}
- fetch.insn = icache_data[idx];
- fetch.func = icache_func[idx];
- return fetch;
}
+ return icache_data[idx];
}
reg_t get_badvaddr() { return badvaddr; }
// implement an instruction cache for simulator performance
static const reg_t ICACHE_ENTRIES = 256;
- insn_t icache_data[ICACHE_ENTRIES];
- insn_func_t icache_func[ICACHE_ENTRIES];
+ insn_fetch_t icache_data[ICACHE_ENTRIES];
// implement a TLB for simulator performance
static const reg_t TLB_ENTRIES = 256;
DECLARE_INSN(vlsegstwu, 0xb0b, 0xfff)
DECLARE_INSN(vvcfg, 0x473, 0xf801ffff)
DECLARE_INSN(movz, 0x2f7, 0x1ffff)
-DECLARE_INSN(c_ld, 0x9, 0x1f)
-DECLARE_INSN(c_srli32, 0xc19, 0x1c1f)
DECLARE_INSN(fmin_s, 0x18053, 0x1ffff)
-DECLARE_INSN(c_lw0, 0x12, 0x801f)
DECLARE_INSN(slliw, 0x9b, 0x3f83ff)
DECLARE_INSN(lb, 0x3, 0x3ff)
DECLARE_INSN(vlwu, 0x30b, 0x3fffff)
DECLARE_INSN(add, 0x33, 0x1ffff)
DECLARE_INSN(fcvt_d_s, 0x100d3, 0x3ff1ff)
DECLARE_INSN(mfpcr, 0x17b, 0x3fffff)
-DECLARE_INSN(c_fsd, 0x18, 0x1f)
DECLARE_INSN(fmax_d, 0x190d3, 0x1ffff)
DECLARE_INSN(bne, 0xe3, 0x3ff)
DECLARE_INSN(rdcycle, 0x277, 0x7ffffff)
DECLARE_INSN(vlh, 0x8b, 0x3fffff)
DECLARE_INSN(bgeu, 0x3e3, 0x3ff)
DECLARE_INSN(vflstd, 0x158b, 0x1ffff)
-DECLARE_INSN(c_li, 0x0, 0x1f)
DECLARE_INSN(fadd_d, 0xd3, 0x1f1ff)
DECLARE_INSN(sltiu, 0x193, 0x3ff)
DECLARE_INSN(mtpcr, 0x1fb, 0x1ffff)
DECLARE_INSN(vlb, 0xb, 0x3fffff)
DECLARE_INSN(stop, 0x177, 0xffffffff)
DECLARE_INSN(vld, 0x18b, 0x3fffff)
-DECLARE_INSN(c_slli, 0x19, 0x1c1f)
DECLARE_INSN(break, 0xf7, 0xffffffff)
DECLARE_INSN(fcvt_s_w, 0xe053, 0x3ff1ff)
DECLARE_INSN(vflstw, 0x150b, 0x1ffff)
DECLARE_INSN(mul, 0x433, 0x1ffff)
-DECLARE_INSN(c_lw, 0xa, 0x1f)
DECLARE_INSN(vxcptevac, 0x237b, 0xf83fffff)
DECLARE_INSN(vlw, 0x10b, 0x3fffff)
DECLARE_INSN(vssegstw, 0x90f, 0xfff)
DECLARE_INSN(amominu_d, 0x19ab, 0x1ffff)
-DECLARE_INSN(c_sdsp, 0x6, 0x1f)
DECLARE_INSN(mftx_d, 0x1c0d3, 0x3fffff)
DECLARE_INSN(srli, 0x293, 0x3f03ff)
-DECLARE_INSN(c_srli, 0x819, 0x1c1f)
-DECLARE_INSN(c_ldsp, 0x4, 0x1f)
-DECLARE_INSN(c_flw, 0x14, 0x1f)
-DECLARE_INSN(c_srai32, 0x1419, 0x1c1f)
DECLARE_INSN(amominu_w, 0x192b, 0x1ffff)
DECLARE_INSN(divuw, 0x6bb, 0x1ffff)
DECLARE_INSN(mulw, 0x43b, 0x1ffff)
DECLARE_INSN(feq_s, 0x15053, 0x1ffff)
DECLARE_INSN(fsgnjx_d, 0x70d3, 0x1ffff)
DECLARE_INSN(sra, 0x102b3, 0x1ffff)
-DECLARE_INSN(c_lwsp, 0x5, 0x1f)
DECLARE_INSN(bge, 0x2e3, 0x3ff)
DECLARE_INSN(venqimm2, 0x337b, 0xf801ffff)
-DECLARE_INSN(c_add3, 0x1c, 0x31f)
DECLARE_INSN(sraiw, 0x1029b, 0x3f83ff)
DECLARE_INSN(vssegd, 0x218f, 0x1ffff)
DECLARE_INSN(srl, 0x2b3, 0x1ffff)
DECLARE_INSN(rdinstret, 0xa77, 0x7ffffff)
DECLARE_INSN(fcvt_wu_d, 0xb0d3, 0x3ff1ff)
DECLARE_INSN(subw, 0x1003b, 0x1ffff)
-DECLARE_INSN(c_swsp, 0x8, 0x1f)
DECLARE_INSN(fmax_s, 0x19053, 0x1ffff)
DECLARE_INSN(amomaxu_d, 0x1dab, 0x1ffff)
-DECLARE_INSN(c_slliw, 0x1819, 0x1c1f)
-DECLARE_INSN(c_fld, 0x15, 0x1f)
DECLARE_INSN(vlstw, 0x110b, 0x1ffff)
DECLARE_INSN(vlsth, 0x108b, 0x1ffff)
DECLARE_INSN(xori, 0x213, 0x3ff)
DECLARE_INSN(fcvt_wu_s, 0xb053, 0x3ff1ff)
DECLARE_INSN(vlstb, 0x100b, 0x1ffff)
DECLARE_INSN(vlstd, 0x118b, 0x1ffff)
-DECLARE_INSN(c_ld0, 0x8012, 0x801f)
DECLARE_INSN(rdtime, 0x677, 0x7ffffff)
DECLARE_INSN(andi, 0x393, 0x3ff)
DECLARE_INSN(clearpcr, 0x7b, 0x3ff)
DECLARE_INSN(jal, 0x6f, 0x7f)
DECLARE_INSN(lwu, 0x303, 0x3ff)
DECLARE_INSN(vlsegstbu, 0xa0b, 0xfff)
-DECLARE_INSN(c_beq, 0x10, 0x1f)
DECLARE_INSN(vlhu, 0x28b, 0x3fffff)
DECLARE_INSN(vfsstd, 0x158f, 0x1ffff)
DECLARE_INSN(fnmadd_d, 0xcf, 0x1ff)
DECLARE_INSN(amoadd_d, 0x1ab, 0x1ffff)
-DECLARE_INSN(c_sw, 0xd, 0x1f)
DECLARE_INSN(lr_d, 0x101ab, 0x3fffff)
-DECLARE_INSN(c_move, 0x2, 0x801f)
DECLARE_INSN(fcvt_w_s, 0xa053, 0x3ff1ff)
-DECLARE_INSN(c_fsw, 0x16, 0x1f)
-DECLARE_INSN(c_j, 0x8002, 0x801f)
DECLARE_INSN(mulhsu, 0x533, 0x1ffff)
-DECLARE_INSN(c_sd, 0xc, 0x1f)
DECLARE_INSN(amoadd_w, 0x12b, 0x1ffff)
DECLARE_INSN(fcvt_d_lu, 0xd0d3, 0x3ff1ff)
DECLARE_INSN(amomax_d, 0x15ab, 0x1ffff)
DECLARE_INSN(fsd, 0x1a7, 0x3ff)
DECLARE_INSN(fcvt_w_d, 0xa0d3, 0x3ff1ff)
DECLARE_INSN(fmovz, 0xaf7, 0x1ffff)
-DECLARE_INSN(c_or3, 0x21c, 0x31f)
DECLARE_INSN(vmvv, 0x73, 0x3fffff)
DECLARE_INSN(vfssegstw, 0xd0f, 0xfff)
DECLARE_INSN(slt, 0x133, 0x1ffff)
DECLARE_INSN(remw, 0x73b, 0x1ffff)
DECLARE_INSN(sltu, 0x1b3, 0x1ffff)
DECLARE_INSN(slli, 0x93, 0x3f03ff)
-DECLARE_INSN(c_and3, 0x31c, 0x31f)
DECLARE_INSN(vssegw, 0x210f, 0x1ffff)
DECLARE_INSN(amoor_w, 0xd2b, 0x1ffff)
DECLARE_INSN(vsd, 0x18f, 0x3fffff)
DECLARE_INSN(vlsegstw, 0x90b, 0xfff)
DECLARE_INSN(syscall, 0x77, 0xffffffff)
DECLARE_INSN(fsgnj_s, 0x5053, 0x1ffff)
-DECLARE_INSN(c_addi, 0x1, 0x1f)
DECLARE_INSN(vfmvv, 0x173, 0x3fffff)
DECLARE_INSN(vlstwu, 0x130b, 0x1ffff)
-DECLARE_INSN(c_sub3, 0x11c, 0x31f)
DECLARE_INSN(vsh, 0x8f, 0x3fffff)
DECLARE_INSN(vlsegstb, 0x80b, 0xfff)
DECLARE_INSN(vxcptsave, 0x37b, 0xf83fffff)
DECLARE_INSN(amomax_w, 0x152b, 0x1ffff)
DECLARE_INSN(fsgnj_d, 0x50d3, 0x1ffff)
DECLARE_INSN(vflsegstw, 0xd0b, 0xfff)
-DECLARE_INSN(c_sub, 0x801a, 0x801f)
DECLARE_INSN(mulhu, 0x5b3, 0x1ffff)
DECLARE_INSN(fence_v_g, 0x2af, 0x3ff)
DECLARE_INSN(vmsv, 0x873, 0x3fffff)
DECLARE_INSN(fcvt_s_l, 0xc053, 0x3ff1ff)
DECLARE_INSN(vflsegstd, 0xd8b, 0xfff)
DECLARE_INSN(auipc, 0x17, 0x7f)
-DECLARE_INSN(c_add, 0x1a, 0x801f)
DECLARE_INSN(fcvt_lu_d, 0x90d3, 0x3ff1ff)
DECLARE_INSN(vfld, 0x58b, 0x3fffff)
DECLARE_INSN(sc_d, 0x105ab, 0x1ffff)
DECLARE_INSN(vssegh, 0x208f, 0x1ffff)
DECLARE_INSN(fsqrt_s, 0x4053, 0x3ff1ff)
DECLARE_INSN(vxcptkill, 0xb7b, 0xffffffff)
-DECLARE_INSN(c_srai, 0x1019, 0x1c1f)
DECLARE_INSN(amomin_w, 0x112b, 0x1ffff)
DECLARE_INSN(fsgnjn_s, 0x6053, 0x1ffff)
-DECLARE_INSN(c_slli32, 0x419, 0x1c1f)
DECLARE_INSN(vlsegwu, 0x230b, 0x1ffff)
DECLARE_INSN(vfsw, 0x50f, 0x3fffff)
DECLARE_INSN(amoswap_d, 0x5ab, 0x1ffff)
DECLARE_INSN(fsqrt_d, 0x40d3, 0x3ff1ff)
DECLARE_INSN(vflw, 0x50b, 0x3fffff)
-DECLARE_INSN(c_bne, 0x11, 0x1f)
DECLARE_INSN(fmadd_d, 0xc3, 0x1ff)
DECLARE_INSN(divw, 0x63b, 0x1ffff)
DECLARE_INSN(amomin_d, 0x11ab, 0x1ffff)
DECLARE_INSN(sw, 0x123, 0x3ff)
DECLARE_INSN(fmsub_s, 0x47, 0x1ff)
DECLARE_INSN(vfssegw, 0x250f, 0x1ffff)
-DECLARE_INSN(c_addiw, 0x1d, 0x1f)
DECLARE_INSN(lhu, 0x283, 0x3ff)
DECLARE_INSN(sh, 0xa3, 0x3ff)
DECLARE_INSN(vlsegw, 0x210b, 0x1ffff)