refactor disassembler, and add hwacha disassembler
[riscv-isa-sim.git] / riscv / disasm.h
1 // See LICENSE for license details.
2
3 #ifndef _RISCV_DISASM_H
4 #define _RISCV_DISASM_H
5
6 #include "decode.h"
7 #include <string>
8 #include <sstream>
9 #include <vector>
10
11 class arg_t
12 {
13 public:
14 virtual std::string to_string(insn_t val) const = 0;
15 virtual ~arg_t() {}
16 };
17
18 class disasm_insn_t
19 {
20 public:
21 disasm_insn_t(const char* name, uint32_t match, uint32_t mask,
22 const std::vector<const arg_t*>& args)
23 : match(match), mask(mask), args(args), name(name) {}
24
25 bool operator == (insn_t insn) const
26 {
27 return (insn.bits() & mask) == match;
28 }
29
30 std::string to_string(insn_t insn) const
31 {
32 std::stringstream s;
33 int len;
34 for (len = 0; name[len]; len++)
35 s << (name[len] == '_' ? '.' : name[len]);
36
37 if (args.size())
38 {
39 s << std::string(std::max(1, 8 - len), ' ');
40 for (size_t i = 0; i < args.size()-1; i++)
41 s << args[i]->to_string(insn) << ", ";
42 s << args[args.size()-1]->to_string(insn);
43 }
44 return s.str();
45 }
46
47 uint32_t get_match() const { return match; }
48 uint32_t get_mask() const { return mask; }
49
50 private:
51 uint32_t match;
52 uint32_t mask;
53 std::vector<const arg_t*> args;
54 const char* name;
55 };
56
57 class disassembler_t
58 {
59 public:
60 disassembler_t();
61 ~disassembler_t();
62 std::string disassemble(insn_t insn);
63 void add_insn(disasm_insn_t* insn);
64 private:
65 static const int HASH_SIZE = 256;
66 std::vector<const disasm_insn_t*> chain[HASH_SIZE+1];
67 const disasm_insn_t* lookup(insn_t insn);
68 };
69
70 #endif