From cb6cfc5f3ad18280c6dce1f03ee4ff87e4677dad Mon Sep 17 00:00:00 2001 From: Yunsup Lee Date: Fri, 18 Oct 2013 17:34:54 -0700 Subject: [PATCH] refactor disassembler, and add hwacha disassembler --- .gitignore | 1 + hwacha/hwacha.cc | 1 + hwacha/hwacha.h | 8 ++ hwacha/hwacha.mk.in | 2 + hwacha/hwacha_disasm.cc | 200 ++++++++++++++++++++++++++++++++++++++++ hwacha/insns/vf.h | 17 +++- riscv/disasm.cc | 123 +++--------------------- riscv/disasm.h | 55 ++++++++++- riscv/extension.h | 3 + riscv/interactive.cc | 9 +- riscv/processor.cc | 30 +++--- riscv/processor.h | 11 ++- riscv/riscv-dis.cc | 2 +- riscv/rocc.cc | 6 ++ riscv/rocc.h | 1 + riscv/sim.cc | 17 +++- riscv/sim.h | 5 +- 17 files changed, 347 insertions(+), 144 deletions(-) create mode 100644 hwacha/hwacha_disasm.cc diff --git a/.gitignore b/.gitignore index 12a75cd..031e691 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ autom4te.cache/ +.*.swp diff --git a/hwacha/hwacha.cc b/hwacha/hwacha.cc index 0d6b906..192d308 100644 --- a/hwacha/hwacha.cc +++ b/hwacha/hwacha.cc @@ -1,5 +1,6 @@ #include "hwacha.h" #include "hwacha_xcpt.h" +#include "mmu.h" #include "trap.h" void ct_state_t::reset() diff --git a/hwacha/hwacha.h b/hwacha/hwacha.h index e48bf52..7504e57 100644 --- a/hwacha/hwacha.h +++ b/hwacha/hwacha.h @@ -30,9 +30,12 @@ struct ut_state_t class hwacha_t : public extension_t { public: + hwacha_t() : debug(false) {} std::vector get_instructions(); + std::vector get_disasms(); const char* name() { return "hwacha"; } void reset(); + void set_debug(bool value) { debug = value; } ct_state_t* get_ct_state() { return &ct_state; } ut_state_t* get_ut_state(int idx) { return &ut_state[idx]; } @@ -40,10 +43,15 @@ public: void take_exception(reg_t, reg_t); void clear_exception() { clear_interrupt(); } + bool get_debug() { return debug; } + disassembler_t* get_ut_disassembler() { return &ut_disassembler; } + private: static const int max_uts = 2048; ct_state_t ct_state; ut_state_t ut_state[max_uts]; + disassembler_t ut_disassembler; + bool debug; }; REGISTER_EXTENSION(hwacha, []() { return new hwacha_t; }) diff --git a/hwacha/hwacha.mk.in b/hwacha/hwacha.mk.in index cf698d3..bf16b6f 100644 --- a/hwacha/hwacha.mk.in +++ b/hwacha/hwacha.mk.in @@ -9,6 +9,7 @@ hwacha_install_prog_srcs = \ hwacha_hdrs = \ hwacha.h \ + hwacha_xcpt.h \ decode_hwacha.h \ decode_hwacha_ut.h \ opcodes_hwacha.h \ @@ -16,6 +17,7 @@ hwacha_hdrs = \ hwacha_srcs = \ hwacha.cc \ + hwacha_disasm.cc \ $(hwacha_gen_srcs) \ $(hwacha_ut_gen_srcs) \ diff --git a/hwacha/hwacha_disasm.cc b/hwacha/hwacha_disasm.cc new file mode 100644 index 0000000..46ec080 --- /dev/null +++ b/hwacha/hwacha_disasm.cc @@ -0,0 +1,200 @@ +#include "hwacha.h" + +static const char* xpr[] = { + "zero", "ra", "s0", "s1", "s2", "s3", "s4", "s5", + "s6", "s7", "s8", "s9", "s10", "s11", "sp", "tp", + "v0", "v1", "a0", "a1", "a2", "a3", "a4", "a5", + "a6", "a7", "t0", "t1", "t2", "t3", "t4", "gp" +}; + +static const char* fpr[] = { + "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", + "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15", + "fv0", "fv1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", + "fa6", "fa7", "ft0", "ft1", "ft2", "ft3", "ft4", "ft5" +}; + +static const char* vxpr[] = { + "vx0", "vx1", "vx2", "vx3", "vx4", "vx5", "vx6", "vx7", + "vx8", "vx9", "vx10", "vx11", "vx12", "vx13", "vx14", "vx15", + "vx16", "vx17", "vx18", "vx19", "vx20", "vx21", "vx22", "vx23", + "vx24", "vx25", "vx26", "vx27", "vx28", "vx29", "vx30", "vx31" +}; + +static const char* vfpr[] = { + "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", + "vf8", "vf9", "vf10", "vf11", "vf12", "vf13", "vf14", "vf15", + "vf16", "vf17", "vf18", "vf19", "vf20", "vf21", "vf22", "vf23", + "vf24", "vf25", "vf26", "vf27", "vf28", "vf29", "vf30", "vf31" +}; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return xpr[insn.rs1()]; + } +} xrs1; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return xpr[insn.rs2()]; + } +} xrs2; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return xpr[insn.rd()]; + } +} xrd; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return fpr[insn.rd()]; + } +} frd; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return fpr[insn.rs1()]; + } +} frs1; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return fpr[insn.rs2()]; + } +} frs2; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return fpr[insn.rs3()]; + } +} frs3; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return vxpr[insn.rd()]; + } +} vxrd; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return vxpr[insn.rs1()]; + } +} vxrs1; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return vfpr[insn.rd()]; + } +} vfrd; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return vfpr[insn.rs1()]; + } +} vfrs1; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string(insn.i_imm() & 0x3f); + } +} nxregs; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((insn.i_imm() >> 6) & 0x3f); + } +} nfregs; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.s_imm()) + '(' + xpr[insn.rs1()] + ')'; + } +} vf_addr; + +std::vector hwacha_t::get_disasms() +{ + std::vector insns; + + #define DECLARE_INSN(code, match, mask) \ + const uint32_t match_##code = match; \ + const uint32_t mask_##code = mask; + #include "opcodes_hwacha.h" + #undef DECLARE_INSN + + #define DISASM_INSN(name, code, extra, ...) \ + insns.push_back(new disasm_insn_t(name, match_##code, mask_##code | (extra), __VA_ARGS__)); + + DISASM_INSN("vsetcfg", vsetcfg, 0, {&xrs1, &nxregs, &nfregs}); + DISASM_INSN("vsetvl", vsetvl, 0, {&xrd, &xrs1}); + DISASM_INSN("vgetcfg", vgetcfg, 0, {&xrd}); + DISASM_INSN("vgetvl", vgetvl, 0, {&xrd}); + + DISASM_INSN("vmvv", vmvv, 0, {&vxrd, &vxrs1}); + DISASM_INSN("vmsv", vmsv, 0, {&vxrd, &xrs1}); + DISASM_INSN("vf", vf, 0, {&vf_addr}); + + DISASM_INSN("vxcptcause", vxcptcause, 0, {&xrd}); + DISASM_INSN("vxcptaux", vxcptaux, 0, {&xrd}); + DISASM_INSN("vxcptsave", vxcptsave, 0, {&xrs1}); + DISASM_INSN("vxcptrestore", vxcptrestore, 0, {&xrs1}); + DISASM_INSN("vxcptkill", vxcptkill, 0, {}); + + const uint32_t mask_vseglen = 0x7UL << 29; + + #define DISASM_VMEM_INSN(name1, name2, code, ...) \ + DISASM_INSN(name1, code, mask_vseglen, __VA_ARGS__) \ + DISASM_INSN(name2, code, 0, __VA_ARGS__) \ + + DISASM_VMEM_INSN("vld", "vlsegd", vlsegd, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vlw", "vlsegw", vlsegw, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vlwu", "vlsegwu", vlsegwu, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vlh", "vlsegh", vlsegh, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vlhu", "vlseghu", vlseghu, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vlb", "vlsegb", vlsegb, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vlbu", "vlsegbu", vlsegbu, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vfld", "vflsegd", vflsegd, {&vfrd, &xrs1}); + DISASM_VMEM_INSN("vflw", "vflsegw", vflsegw, {&vfrd, &xrs1}); + + DISASM_VMEM_INSN("vlstd", "vlsegstd", vlsegstd, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vlstw", "vlsegstw", vlsegstw, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vlstwu", "vlsegstwu", vlsegstwu, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vlsth", "vlsegsth", vlsegsth, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vlsthu", "vlsegsthu", vlsegsthu, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vlstb", "vlsegstb", vlsegstb, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vlstbu", "vlsegstbu", vlsegstbu, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vflstd", "vflsegstd", vflsegstd, {&vfrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vflstw", "vflsegstw", vflsegstw, {&vfrd, &xrs1, &xrs2}); + + DISASM_VMEM_INSN("vsd", "vssegd", vssegd, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vsw", "vssegw", vssegw, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vsh", "vssegh", vssegh, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vsb", "vssegb", vssegb, {&vxrd, &xrs1}); + DISASM_VMEM_INSN("vfsd", "vfssegd", vfssegd, {&vfrd, &xrs1}); + DISASM_VMEM_INSN("vfsw", "vfssegw", vfssegw, {&vfrd, &xrs1}); + + DISASM_VMEM_INSN("vsstd", "vssegstd", vssegstd, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vsstw", "vssegstw", vssegstw, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vssth", "vssegsth", vssegsth, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vsstb", "vssegstb", vssegstb, {&vxrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vfsstd", "vfssegstd", vfssegstd, {&vfrd, &xrs1, &xrs2}); + DISASM_VMEM_INSN("vfsstw", "vfssegstw", vfssegstw, {&vfrd, &xrs1, &xrs2}); + + #define DECLARE_INSN(code, match, mask) \ + const uint32_t match_##code = match; \ + const uint32_t mask_##code = mask; + #include "opcodes_hwacha_ut.h" + #undef DECLARE_INSN + + #define DISASM_UT_INSN(name, code, extra, ...) \ + ut_disassembler.add_insn(new disasm_insn_t(name, match_##code, mask_##code | (extra), __VA_ARGS__)); + + DISASM_UT_INSN("stop", ut_stop, 0, {}); + DISASM_UT_INSN("utidx", ut_utidx, 0, {&xrd}); + DISASM_UT_INSN("movz", ut_movz, 0, {&xrd, &xrs1, &xrs2}); + DISASM_UT_INSN("movn", ut_movn, 0, {&xrd, &xrs1, &xrs2}); + DISASM_UT_INSN("fmovz", ut_fmovz, 0, {&frd, &xrs1, &frs2}); + DISASM_UT_INSN("fmovn", ut_fmovn, 0, {&frd, &xrs1, &frs2}); + + return insns; +} diff --git a/hwacha/insns/vf.h b/hwacha/insns/vf.h index 7bd1973..fafb8b9 100644 --- a/hwacha/insns/vf.h +++ b/hwacha/insns/vf.h @@ -5,11 +5,12 @@ if (VL) { h->get_ut_state(i)->run = true; } +vf_loop: + if (VF_PC & 3) h->take_exception(HWACHA_CAUSE_VF_MISALIGNED_FETCH, VF_PC); - mmu_t::insn_fetch_t ut_fetch = p->get_mmu()->load_insn(VF_PC); - insn_t ut_insn = ut_fetch.insn.insn; + insn_t ut_insn = p->get_mmu()->load_insn(VF_PC).insn.insn; bool matched = false; @@ -25,7 +26,13 @@ if (VL) { if (!matched) h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_INSTRUCTION, VF_PC); - // if vf is still running, rewind pc so that it will execute again - if (h->vf_active()) - npc = pc; + if (!h->get_debug()) { + if (h->vf_active()) + goto vf_loop; + } else { + fprintf(stderr, "vf block: 0x%016" PRIx64 " (0x%08" PRIx32 ") %s\n", + VF_PC, ut_insn.bits(), h->get_ut_disassembler()->disassemble(ut_insn).c_str()); + if (h->vf_active()) + npc = pc; + } } diff --git a/riscv/disasm.cc b/riscv/disasm.cc index caf4ff4..436aea3 100644 --- a/riscv/disasm.cc +++ b/riscv/disasm.cc @@ -6,14 +6,6 @@ #include #include #include -using namespace std; - -class arg_t -{ - public: - virtual string to_string(insn_t val) const = 0; - virtual ~arg_t() {} -}; static const char* xpr[] = { "zero", "ra", "s0", "s1", "s2", "s3", "s4", "s5", @@ -29,35 +21,21 @@ static const char* fpr[] = { "fa6", "fa7", "ft0", "ft1", "ft2", "ft3", "ft4", "ft5" }; -static const char* vxpr[] = { - "vx0", "vx1", "vx2", "vx3", "vx4", "vx5", "vx6", "vx7", - "vx8", "vx9", "vx10", "vx11", "vx12", "vx13", "vx14", "vx15", - "vx16", "vx17", "vx18", "vx19", "vx20", "vx21", "vx22", "vx23", - "vx24", "vx25", "vx26", "vx27", "vx28", "vx29", "vx30", "vx31" -}; - -static const char* vfpr[] = { - "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7", - "vf8", "vf9", "vf10", "vf11", "vf12", "vf13", "vf14", "vf15", - "vf16", "vf17", "vf18", "vf19", "vf20", "vf21", "vf22", "vf23", - "vf24", "vf25", "vf26", "vf27", "vf28", "vf29", "vf30", "vf31" -}; - struct : public arg_t { - string to_string(insn_t insn) const { - return ::to_string((int)insn.i_imm()) + '(' + xpr[insn.rs1()] + ')'; + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.i_imm()) + '(' + xpr[insn.rs1()] + ')'; } } load_address; struct : public arg_t { - string to_string(insn_t insn) const { - return ::to_string((int)insn.s_imm()) + '(' + xpr[insn.rs1()] + ')'; + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.s_imm()) + '(' + xpr[insn.rs1()] + ')'; } } store_address; struct : public arg_t { - string to_string(insn_t insn) const { - return string("0(") + xpr[insn.rs1()] + ')'; + std::string to_string(insn_t insn) const { + return std::string("0(") + xpr[insn.rs1()] + ')'; } } amo_address; @@ -105,49 +83,13 @@ struct : public arg_t { struct : public arg_t { std::string to_string(insn_t insn) const { - return vxpr[insn.rd()]; - } -} vxrd; - -struct : public arg_t { - std::string to_string(insn_t insn) const { - return vxpr[insn.rs1()]; - } -} vxrs1; - -struct : public arg_t { - std::string to_string(insn_t insn) const { - return vfpr[insn.rd()]; - } -} vfrd; - -struct : public arg_t { - std::string to_string(insn_t insn) const { - return vfpr[insn.rs1()]; - } -} vfrs1; - -struct : public arg_t { - std::string to_string(insn_t insn) const { - return ::to_string(insn.i_imm() & 0x3f); - } -} nxregs; - -struct : public arg_t { - std::string to_string(insn_t insn) const { - return ::to_string((insn.i_imm() >> 6) & 0x3f); - } -} nfregs; - -struct : public arg_t { - std::string to_string(insn_t insn) const { - return string("pcr") + xpr[insn.rs1()]; + return std::string("pcr") + xpr[insn.rs1()]; } } pcr; struct : public arg_t { std::string to_string(insn_t insn) const { - return ::to_string((int)insn.i_imm()); + return std::to_string((int)insn.i_imm()); } } imm; @@ -179,52 +121,13 @@ struct : public arg_t { } } jump_target; -class disasm_insn_t -{ - public: - disasm_insn_t(const char* name, uint32_t match, uint32_t mask, - const std::vector& args) - : match(match), mask(mask), args(args), name(name) {} - - bool operator == (insn_t insn) const - { - return (insn.bits() & mask) == match; - } - - std::string to_string(insn_t insn) const - { - std::stringstream s; - int len; - for (len = 0; name[len]; len++) - s << (name[len] == '_' ? '.' : name[len]); - - if (args.size()) - { - s << std::string(std::max(1, 8 - len), ' '); - for (size_t i = 0; i < args.size()-1; i++) - s << args[i]->to_string(insn) << ", "; - s << args[args.size()-1]->to_string(insn); - } - return s.str(); - } - - uint32_t get_match() const { return match; } - uint32_t get_mask() const { return mask; } - - private: - uint32_t match; - uint32_t mask; - std::vector args; - const char* name; -}; - -std::string disassembler::disassemble(insn_t insn) +std::string disassembler_t::disassemble(insn_t insn) { const disasm_insn_t* disasm_insn = lookup(insn); return disasm_insn ? disasm_insn->to_string(insn) : "unknown"; } -disassembler::disassembler() +disassembler_t::disassembler_t() { const uint32_t mask_rd = 0x1fUL << 7; const uint32_t match_rd_ra = 1UL << 7; @@ -463,7 +366,7 @@ disassembler::disassembler() #undef DECLARE_INSN } -const disasm_insn_t* disassembler::lookup(insn_t insn) +const disasm_insn_t* disassembler_t::lookup(insn_t insn) { size_t idx = insn.bits() % HASH_SIZE; for (size_t j = 0; j < chain[idx].size(); j++) @@ -478,7 +381,7 @@ const disasm_insn_t* disassembler::lookup(insn_t insn) return NULL; } -void disassembler::add_insn(disasm_insn_t* insn) +void disassembler_t::add_insn(disasm_insn_t* insn) { size_t idx = HASH_SIZE; if (insn->get_mask() % HASH_SIZE == HASH_SIZE - 1) @@ -486,7 +389,7 @@ void disassembler::add_insn(disasm_insn_t* insn) chain[idx].push_back(insn); } -disassembler::~disassembler() +disassembler_t::~disassembler_t() { for (size_t i = 0; i < HASH_SIZE+1; i++) for (size_t j = 0; j < chain[i].size(); j++) diff --git a/riscv/disasm.h b/riscv/disasm.h index ee6d919..b5aa6de 100644 --- a/riscv/disasm.h +++ b/riscv/disasm.h @@ -5,20 +5,65 @@ #include "decode.h" #include +#include #include -struct disasm_insn_t; +class arg_t +{ + public: + virtual std::string to_string(insn_t val) const = 0; + virtual ~arg_t() {} +}; -class disassembler +class disasm_insn_t { public: - disassembler(); - ~disassembler(); + disasm_insn_t(const char* name, uint32_t match, uint32_t mask, + const std::vector& args) + : match(match), mask(mask), args(args), name(name) {} + + bool operator == (insn_t insn) const + { + return (insn.bits() & mask) == match; + } + + std::string to_string(insn_t insn) const + { + std::stringstream s; + int len; + for (len = 0; name[len]; len++) + s << (name[len] == '_' ? '.' : name[len]); + + if (args.size()) + { + s << std::string(std::max(1, 8 - len), ' '); + for (size_t i = 0; i < args.size()-1; i++) + s << args[i]->to_string(insn) << ", "; + s << args[args.size()-1]->to_string(insn); + } + return s.str(); + } + + uint32_t get_match() const { return match; } + uint32_t get_mask() const { return mask; } + + private: + uint32_t match; + uint32_t mask; + std::vector args; + const char* name; +}; + +class disassembler_t +{ + public: + disassembler_t(); + ~disassembler_t(); std::string disassemble(insn_t insn); + void add_insn(disasm_insn_t* insn); private: static const int HASH_SIZE = 256; std::vector chain[HASH_SIZE+1]; - void add_insn(disasm_insn_t* insn); const disasm_insn_t* lookup(insn_t insn); }; diff --git a/riscv/extension.h b/riscv/extension.h index da42db9..cce8345 100644 --- a/riscv/extension.h +++ b/riscv/extension.h @@ -2,6 +2,7 @@ #define _RISCV_COPROCESSOR_H #include "processor.h" +#include "disasm.h" #include #include #include @@ -11,8 +12,10 @@ class extension_t { public: virtual std::vector get_instructions() = 0; + virtual std::vector get_disasms() = 0; virtual const char* name() = 0; virtual void reset() {}; + virtual void set_debug(bool value) {}; virtual ~extension_t(); void set_processor(processor_t* _p) { p = _p; } diff --git a/riscv/interactive.cc b/riscv/interactive.cc index a1b7dd0..ad38ace 100644 --- a/riscv/interactive.cc +++ b/riscv/interactive.cc @@ -56,7 +56,8 @@ void sim_t::interactive() if (!(ss >> cmd)) { - step(1, true); + set_procs_debug(true); + step(1); continue; } @@ -101,8 +102,9 @@ void sim_t::interactive_run(const std::string& cmd, const std::vector& args) @@ -269,6 +271,7 @@ void sim_t::interactive_until(const std::string& cmd, const std::vector processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id) - : sim(_sim), mmu(_mmu), ext(NULL), id(_id), opcode_bits(0) + : sim(_sim), mmu(_mmu), ext(NULL), id(_id), debug(false), opcode_bits(0) { reset(true); mmu->set_processor(this); @@ -59,6 +59,13 @@ void state_t::reset() load_reservation = -1; } +void processor_t::set_debug(bool value) +{ + debug = value; + if (ext) + ext->set_debug(value); +} + void processor_t::reset(bool value) { if (run == !value) @@ -88,7 +95,7 @@ void processor_t::take_interrupt() throw trap_t((1ULL << ((state.sr & SR_S64) ? 63 : 31)) + i); } -void processor_t::step(size_t n, bool noisy) +void processor_t::step(size_t n) { if(!run) return; @@ -105,7 +112,7 @@ void processor_t::step(size_t n, bool noisy) #define execute_insn(noisy) \ do { \ mmu_t::insn_fetch_t fetch = _mmu->load_insn(npc); \ - if(noisy) disasm(fetch.insn.insn, npc); \ + if(noisy) disasm(fetch.insn.insn); \ npc = fetch.func(this, fetch.insn.insn, npc); \ } while(0) @@ -117,7 +124,7 @@ void processor_t::step(size_t n, bool noisy) #define execute_insn(noisy) \ do { \ mmu_t::insn_fetch_t fetch = _mmu->load_insn(npc); \ - if(noisy) disasm(fetch.insn.insn, npc); \ + if(noisy) disasm(fetch.insn.insn); \ bool in_spvr = state.sr & SR_S; \ if (!in_spvr) fprintf(stderr, "\n0x%016" PRIx64 " (0x%08" PRIx32 ") ", npc, fetch.insn.insn.bits()); \ /*if (!in_spvr) fprintf(stderr, "\n0x%016" PRIx64 " (0x%08" PRIx32 ") %s ", npc, fetch.insn.insn.bits(), disasmblr.disassemble(fetch.insn.insn).c_str());*/ \ @@ -125,7 +132,7 @@ void processor_t::step(size_t n, bool noisy) } while(0) #endif - if(noisy) for( ; i < n; i++) // print out instructions as we go + if(debug) for( ; i < n; i++) // print out instructions as we go execute_insn(true); else { @@ -145,7 +152,7 @@ void processor_t::step(size_t n, bool noisy) } catch(trap_t& t) { - take_trap(npc, t, noisy); + take_trap(npc, t); } state.cycle += i; @@ -157,9 +164,9 @@ void processor_t::step(size_t n, bool noisy) set_interrupt(IRQ_TIMER, true); } -void processor_t::take_trap(reg_t pc, trap_t& t, bool noisy) +void processor_t::take_trap(reg_t pc, trap_t& t) { - if (noisy) + if (debug) fprintf(stderr, "core %3d: exception %s, epc 0x%016" PRIx64 "\n", id, t.name(), pc); @@ -182,12 +189,11 @@ void processor_t::deliver_ipi() set_pcr(PCR_CLR_IPI, 1); } -void processor_t::disasm(insn_t insn, reg_t pc) +void processor_t::disasm(insn_t insn) { // the disassembler is stateless, so we share it - static disassembler disasm; fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIx32 ") %s\n", - id, state.pc, insn.bits(), disasm.disassemble(insn).c_str()); + id, state.pc, insn.bits(), disassembler.disassemble(insn).c_str()); } reg_t processor_t::set_pcr(int which, reg_t val) @@ -342,6 +348,8 @@ void processor_t::register_extension(extension_t* x) { for (auto insn : x->get_instructions()) register_insn(insn); + for (auto disasm_insn : x->get_disasms()) + disassembler.add_insn(disasm_insn); if (ext != NULL) throw std::logic_error("only one extension may be registered"); ext = x; diff --git a/riscv/processor.h b/riscv/processor.h index 6b007f2..0256bd8 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -1,9 +1,9 @@ // See LICENSE for license details. - #ifndef _RISCV_PROCESSOR_H #define _RISCV_PROCESSOR_H #include "decode.h" +#include "disasm.h" #include #include "config.h" #include @@ -59,8 +59,9 @@ public: processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id); ~processor_t(); + void set_debug(bool value); void reset(bool value); - void step(size_t n, bool noisy); // run for n cycles + void step(size_t n); // run for n cycles void deliver_ipi(); // register an interprocessor interrupt bool running() { return run; } reg_t set_pcr(int which, reg_t val); @@ -80,16 +81,18 @@ private: sim_t* sim; mmu_t* mmu; // main memory is always accessed via the mmu extension_t* ext; + disassembler_t disassembler; state_t state; uint32_t id; bool run; // !reset + bool debug; unsigned opcode_bits; std::multimap opcode_map; void take_interrupt(); // take a trap if any interrupts are pending - void take_trap(reg_t pc, trap_t& t, bool noisy); // take an exception - void disasm(insn_t insn, reg_t pc); // disassemble and print an instruction + void take_trap(reg_t pc, trap_t& t); // take an exception + void disasm(insn_t insn); // disassemble and print an instruction friend class sim_t; friend class mmu_t; diff --git a/riscv/riscv-dis.cc b/riscv/riscv-dis.cc index 62d522e..fdeb69f 100644 --- a/riscv/riscv-dis.cc +++ b/riscv/riscv-dis.cc @@ -15,7 +15,7 @@ using namespace std; int main() { string s; - disassembler d; + disassembler_t d; while (getline(cin, s)) { diff --git a/riscv/rocc.cc b/riscv/rocc.cc index b148319..7988c01 100644 --- a/riscv/rocc.cc +++ b/riscv/rocc.cc @@ -36,3 +36,9 @@ std::vector rocc_t::get_instructions() insns.push_back((insn_desc_t){0x7b, 0x7f, &::illegal_instruction, c3}); return insns; } + +std::vector rocc_t::get_disasms() +{ + std::vector insns; + return insns; +} diff --git a/riscv/rocc.h b/riscv/rocc.h index e4148ec..63d074d 100644 --- a/riscv/rocc.h +++ b/riscv/rocc.h @@ -29,6 +29,7 @@ class rocc_t : public extension_t virtual reg_t custom2(rocc_insn_t insn, reg_t xs1, reg_t xs2); virtual reg_t custom3(rocc_insn_t insn, reg_t xs1, reg_t xs2); std::vector get_instructions(); + std::vector get_disasms(); }; #endif diff --git a/riscv/sim.cc b/riscv/sim.cc index a4a1c17..4d61555 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -79,16 +79,16 @@ void sim_t::run() if (debug || ctrlc_pressed) interactive(); else - step(INTERLEAVE, false); + step(INTERLEAVE); } } -void sim_t::step(size_t n, bool noisy) +void sim_t::step(size_t n) { for (size_t i = 0, steps = 0; i < n; i += steps) { steps = std::min(n - i, INTERLEAVE - current_step); - procs[current_proc]->step(steps, noisy); + procs[current_proc]->step(steps); current_step += steps; if (current_step == INTERLEAVE) @@ -117,3 +117,14 @@ void sim_t::stop() while (htif->tick()) ; } + +void sim_t::set_debug(bool value) +{ + debug = value; +} + +void sim_t::set_procs_debug(bool value) +{ + for (size_t i=0; i< procs.size(); i++) + procs[i]->set_debug(value); +} diff --git a/riscv/sim.h b/riscv/sim.h index bcb7c1c..e827087 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -22,7 +22,8 @@ public: void run(); bool running(); void stop(); - void set_debug(bool value) { debug = value; } + void set_debug(bool value); + void set_procs_debug(bool value); // deliver an IPI to a specific processor void send_ipi(reg_t who); @@ -41,7 +42,7 @@ private: mmu_t* debug_mmu; // debug port into main memory std::vector procs; - void step(size_t n, bool noisy); // step through simulation + void step(size_t n); // step through simulation static const size_t INTERLEAVE = 5000; size_t current_step; size_t current_proc; -- 2.30.2