aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-06-29 15:00:22 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-06-29 15:02:12 -0700
commit03b8bad375217fbc2143046e8caad9d80301abdb (patch)
treea5649fae5b7eb88825a5f94181820e4affff67b8
parent9b960e91b4d7e44d59fd73a7199517a82ba07c86 (diff)
downloadspike-03b8bad375217fbc2143046e8caad9d80301abdb.zip
spike-03b8bad375217fbc2143046e8caad9d80301abdb.tar.gz
spike-03b8bad375217fbc2143046e8caad9d80301abdb.tar.bz2
Disassemble RVC instructions based on XLEN
The interpretation of RVC opcodes depends on XLEN, and the disassembler always assumed RV32. h/t Michael Clark
-rw-r--r--riscv/disasm.h6
-rw-r--r--riscv/processor.cc7
-rw-r--r--riscv/processor.h1
-rw-r--r--spike_main/disasm.cc26
-rw-r--r--spike_main/spike-dasm.cc12
5 files changed, 31 insertions, 21 deletions
diff --git a/riscv/disasm.h b/riscv/disasm.h
index a8da066..e2981d4 100644
--- a/riscv/disasm.h
+++ b/riscv/disasm.h
@@ -60,14 +60,14 @@ class disasm_insn_t
class disassembler_t
{
public:
- disassembler_t();
+ disassembler_t(int xlen);
~disassembler_t();
- std::string disassemble(insn_t insn);
+ std::string disassemble(insn_t insn) const;
void add_insn(disasm_insn_t* insn);
private:
static const int HASH_SIZE = 256;
std::vector<const disasm_insn_t*> chain[HASH_SIZE+1];
- const disasm_insn_t* lookup(insn_t insn);
+ const disasm_insn_t* lookup(insn_t insn) const;
};
#endif
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 2a31a44..b7500c4 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -22,16 +22,15 @@
processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id,
bool halt_on_reset)
- : debug(false), sim(sim), ext(NULL), disassembler(new disassembler_t),
- id(id), halt_on_reset(halt_on_reset)
+ : debug(false), sim(sim), ext(NULL), id(id), halt_on_reset(halt_on_reset)
{
parse_isa_string(isa);
+ register_base_instructions();
mmu = new mmu_t(sim, this);
+ disassembler = new disassembler_t(max_xlen);
reset();
-
- register_base_instructions();
}
processor_t::~processor_t()
diff --git a/riscv/processor.h b/riscv/processor.h
index 31d5f6c..090ebe7 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -121,6 +121,7 @@ public:
void set_privilege(reg_t);
void yield_load_reservation() { state.load_reservation = (reg_t)-1; }
void update_histogram(reg_t pc);
+ const disassembler_t* get_disassembler() { return disassembler; }
void register_insn(insn_desc_t);
void register_extension(extension_t*);
diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc
index 65977fc..bdbef9c 100644
--- a/spike_main/disasm.cc
+++ b/spike_main/disasm.cc
@@ -248,13 +248,13 @@ struct : public arg_t {
}
} rvc_jump_target;
-std::string disassembler_t::disassemble(insn_t insn)
+std::string disassembler_t::disassemble(insn_t insn) const
{
const disasm_insn_t* disasm_insn = lookup(insn);
return disasm_insn ? disasm_insn->to_string(insn) : "unknown";
}
-disassembler_t::disassembler_t()
+disassembler_t::disassembler_t(int xlen)
{
const uint32_t mask_rd = 0x1fUL << 7;
const uint32_t match_rd_ra = 1UL << 7;
@@ -509,7 +509,6 @@ disassembler_t::disassembler_t()
DISASM_INSN("li", c_li, 0, {&xrd, &rvc_imm});
DISASM_INSN("lui", c_lui, 0, {&xrd, &rvc_uimm});
DISASM_INSN("addi", c_addi, 0, {&xrd, &xrd, &rvc_imm});
- DISASM_INSN("addiw", c_addiw, 0, {&xrd, &xrd, &rvc_imm});
DISASM_INSN("slli", c_slli, 0, {&xrd, &rvc_shamt});
DISASM_INSN("mv", c_mv, 0, {&xrd, &rvc_rs2});
DISASM_INSN("add", c_add, 0, {&xrd, &xrd, &rvc_rs2});
@@ -520,17 +519,28 @@ disassembler_t::disassembler_t()
DISASM_INSN("or", c_or, 0, {&rvc_rs1s, &rvc_rs1s, &rvc_rs2s});
DISASM_INSN("xor", c_xor, 0, {&rvc_rs1s, &rvc_rs1s, &rvc_rs2s});
DISASM_INSN("lw", c_lwsp, 0, {&xrd, &rvc_lwsp_address});
- DISASM_INSN("flw", c_flwsp, 0, {&xrd, &rvc_lwsp_address});
+ DISASM_INSN("fld", c_fld, 0, {&rvc_rs2s, &rvc_ld_address});
DISASM_INSN("sw", c_swsp, 0, {&rvc_rs2, &rvc_swsp_address});
- DISASM_INSN("fsw", c_fswsp, 0, {&rvc_rs2, &rvc_swsp_address});
DISASM_INSN("lw", c_lw, 0, {&rvc_rs2s, &rvc_lw_address});
- DISASM_INSN("flw", c_flw, 0, {&rvc_rs2s, &rvc_lw_address});
DISASM_INSN("sw", c_sw, 0, {&rvc_rs2s, &rvc_lw_address});
- DISASM_INSN("fsw", c_fsw, 0, {&rvc_rs2s, &rvc_lw_address});
DISASM_INSN("beqz", c_beqz, 0, {&rvc_rs1s, &rvc_branch_target});
DISASM_INSN("bnez", c_bnez, 0, {&rvc_rs1s, &rvc_branch_target});
DISASM_INSN("j", c_j, 0, {&rvc_jump_target});
+ if (xlen == 32) {
+ DISASM_INSN("flw", c_flw, 0, {&rvc_rs2s, &rvc_lw_address});
+ DISASM_INSN("flw", c_flwsp, 0, {&xrd, &rvc_lwsp_address});
+ DISASM_INSN("fsw", c_fsw, 0, {&rvc_rs2s, &rvc_lw_address});
+ DISASM_INSN("fsw", c_fswsp, 0, {&rvc_rs2, &rvc_swsp_address});
+ DISASM_INSN("jal", c_jal, 0, {&rvc_jump_target});
+ } else {
+ DISASM_INSN("ld", c_ld, 0, {&rvc_rs2s, &rvc_ld_address});
+ DISASM_INSN("ld", c_ldsp, 0, {&xrd, &rvc_ldsp_address});
+ DISASM_INSN("sd", c_sd, 0, {&rvc_rs2s, &rvc_ld_address});
+ DISASM_INSN("sd", c_sdsp, 0, {&rvc_rs2, &rvc_sdsp_address});
+ DISASM_INSN("addiw", c_addiw, 0, {&xrd, &xrd, &rvc_imm});
+ }
+
// provide a default disassembly for all instructions as a fallback
#define DECLARE_INSN(code, match, mask) \
add_insn(new disasm_insn_t(#code " (args unknown)", match, mask, {}));
@@ -538,7 +548,7 @@ disassembler_t::disassembler_t()
#undef DECLARE_INSN
}
-const disasm_insn_t* disassembler_t::lookup(insn_t insn)
+const disasm_insn_t* disassembler_t::lookup(insn_t insn) const
{
size_t idx = insn.bits() % HASH_SIZE;
for (size_t j = 0; j < chain[idx].size(); j++)
diff --git a/spike_main/spike-dasm.cc b/spike_main/spike-dasm.cc
index aecaa0a..2852835 100644
--- a/spike_main/spike-dasm.cc
+++ b/spike_main/spike-dasm.cc
@@ -17,17 +17,17 @@ using namespace std;
int main(int argc, char** argv)
{
string s;
- disassembler_t d;
+ const char* isa = DEFAULT_ISA;
std::function<extension_t*()> extension;
option_parser_t parser;
parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);});
+ parser.option(0, "isa", 1, [&](const char* s){isa = s;});
parser.parse(argv);
- if (extension) {
- for (auto disasm_insn : extension()->get_disasms())
- d.add_insn(disasm_insn);
- }
+ processor_t p(isa, 0, 0);
+ if (extension)
+ p.register_extension(extension());
while (getline(cin, s))
{
@@ -44,7 +44,7 @@ int main(int argc, char** argv)
if (nbits < 64)
bits = bits << (64 - nbits) >> (64 - nbits);
- string dis = d.disassemble(bits);
+ string dis = p.get_disassembler()->disassemble(bits);
s = s.substr(0, start) + dis + s.substr(end+1);
start += dis.length();
}