diff options
author | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-06-09 21:01:58 -0700 |
---|---|---|
committer | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-06-18 08:56:11 -0700 |
commit | 77adcb1ec93903f7c1d79e2c6a63870b8c8e83d3 (patch) | |
tree | d40daa339ba223a806abd31ce47c0bdd81d0c6a9 | |
parent | 833b965679f4502f83c66353bfc07a092cfac9f6 (diff) | |
download | spike-77adcb1ec93903f7c1d79e2c6a63870b8c8e83d3.zip spike-77adcb1ec93903f7c1d79e2c6a63870b8c8e83d3.tar.gz spike-77adcb1ec93903f7c1d79e2c6a63870b8c8e83d3.tar.bz2 |
rvv: add simple instruction parsing tool
the tool can parse the instruction name from spike debug log to help
dsp kernel designer check what instructions have been used
Signed-off-by: Jerry Shih <bignose1007@gmail.com>
-rw-r--r-- | riscv/disasm.h | 10 | ||||
-rw-r--r-- | spike_main/spike-log-parser.cc | 60 | ||||
-rw-r--r-- | spike_main/spike_main.mk.in | 1 |
3 files changed, 70 insertions, 1 deletions
diff --git a/riscv/disasm.h b/riscv/disasm.h index d322731..e465fca 100644 --- a/riscv/disasm.h +++ b/riscv/disasm.h @@ -40,6 +40,11 @@ class disasm_insn_t return (insn.bits() & mask) == match; } + const char* get_name() const + { + return name; + } + std::string to_string(insn_t insn) const { std::stringstream s; @@ -83,12 +88,15 @@ class disassembler_t public: disassembler_t(int xlen); ~disassembler_t(); + std::string disassemble(insn_t insn) const; + const disasm_insn_t* lookup(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; }; #endif diff --git a/spike_main/spike-log-parser.cc b/spike_main/spike-log-parser.cc new file mode 100644 index 0000000..fd07f53 --- /dev/null +++ b/spike_main/spike-log-parser.cc @@ -0,0 +1,60 @@ +// See LICENSE for license details. + +// This little program finds occurrences of strings like +// core 0: 0x000000008000c36c (0xfe843783) ld a5, -24(s0) +// in its inputs, then output the RISC-V instruction with the disassembly +// enclosed hexadecimal number. + +#include <iostream> +#include <string> +#include <cstdint> +#include <regex> +#include "fesvr/option_parser.h" + +#include "disasm.h" +#include "extension.h" + +using namespace std; + +int main(int argc, char** argv) +{ + string s; + 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); + + processor_t p(isa, DEFAULT_VARCH, 0, 0); + if (extension) { + p.register_extension(extension()); + } + + std::regex reg("^core\\s+\\d+:\\s+0x[0-9a-f]+\\s+\\(0x([0-9a-f]+)\\)", std::regex_constants::icase); + std::smatch m; + std::ssub_match sm ; + + while (getline(cin,s)){ + if (regex_search(s, m, reg)){ + // the opcode string + string op = m[1].str(); + uint32_t bit_num = op.size() * 4; + uint64_t opcode = strtoull(op.c_str(), nullptr, 16); + + if (bit_num<64){ + opcode = opcode << (64-bit_num) >> (64-bit_num); + } + + const disasm_insn_t* disasm = p.get_disassembler()->lookup(opcode); + if (disasm) { + cout << disasm->get_name() << '\n'; + } else { + cout << "unknown_op\n"; + } + } + } + + return 0; +} diff --git a/spike_main/spike_main.mk.in b/spike_main/spike_main.mk.in index 5f7e603..45d7bd4 100644 --- a/spike_main/spike_main.mk.in +++ b/spike_main/spike_main.mk.in @@ -6,6 +6,7 @@ spike_main_subproject_deps = \ spike_main_install_prog_srcs = \ spike.cc \ spike-dasm.cc \ + spike-log-parser.cc \ xspike.cc \ termios-xspike.cc \ |