added support for register convention names in debug mode
[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 static const char* xpr_name[] = {
12 "zero", "ra", "s0", "s1", "s2", "s3", "s4", "s5",
13 "s6", "s7", "s8", "s9", "s10", "s11", "sp", "tp",
14 "v0", "v1", "a0", "a1", "a2", "a3", "a4", "a5",
15 "a6", "a7", "t0", "t1", "t2", "t3", "t4", "gp"
16 };
17
18 static const char* fpr_name[] = {
19 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
20 "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15",
21 "fv0", "fv1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
22 "fa6", "fa7", "ft0", "ft1", "ft2", "ft3", "ft4", "ft5"
23 };
24
25 class arg_t
26 {
27 public:
28 virtual std::string to_string(insn_t val) const = 0;
29 virtual ~arg_t() {}
30 };
31
32 class disasm_insn_t
33 {
34 public:
35 disasm_insn_t(const char* name, uint32_t match, uint32_t mask,
36 const std::vector<const arg_t*>& args)
37 : match(match), mask(mask), args(args), name(name) {}
38
39 bool operator == (insn_t insn) const
40 {
41 return (insn.bits() & mask) == match;
42 }
43
44 std::string to_string(insn_t insn) const
45 {
46 std::stringstream s;
47 int len;
48 for (len = 0; name[len]; len++)
49 s << (name[len] == '_' ? '.' : name[len]);
50
51 if (args.size())
52 {
53 s << std::string(std::max(1, 8 - len), ' ');
54 for (size_t i = 0; i < args.size()-1; i++)
55 s << args[i]->to_string(insn) << ", ";
56 s << args[args.size()-1]->to_string(insn);
57 }
58 return s.str();
59 }
60
61 uint32_t get_match() const { return match; }
62 uint32_t get_mask() const { return mask; }
63
64 private:
65 uint32_t match;
66 uint32_t mask;
67 std::vector<const arg_t*> args;
68 const char* name;
69 };
70
71 class disassembler_t
72 {
73 public:
74 disassembler_t();
75 ~disassembler_t();
76 std::string disassemble(insn_t insn);
77 void add_insn(disasm_insn_t* insn);
78 private:
79 static const int HASH_SIZE = 256;
80 std::vector<const disasm_insn_t*> chain[HASH_SIZE+1];
81 const disasm_insn_t* lookup(insn_t insn);
82 };
83
84 #endif