X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=riscv%2Fdisasm.h;h=94e007a12d32ff254a079313f9b798594cd2e0f2;hb=fa2aaa3f8ad1284f4ca2ae17ad173eb1605fea1a;hp=ee6d9190920cd433beb1b9e4ad7c8835e559a7f1;hpb=28ac3dbd81ee2f7e29944a40507c5fb9843e1e9a;p=riscv-isa-sim.git diff --git a/riscv/disasm.h b/riscv/disasm.h index ee6d919..94e007a 100644 --- a/riscv/disasm.h +++ b/riscv/disasm.h @@ -5,21 +5,70 @@ #include "decode.h" #include +#include #include -struct disasm_insn_t; +extern const char* xpr_name[NXPR]; +extern const char* fpr_name[NFPR]; +extern const char* csr_name(int which); -class disassembler +class arg_t { public: - disassembler(); - ~disassembler(); - std::string disassemble(insn_t insn); + virtual std::string to_string(insn_t val) const = 0; + virtual ~arg_t() {} +}; + +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; +}; + +class disassembler_t +{ + public: + disassembler_t(int xlen); + ~disassembler_t(); + std::string disassemble(insn_t insn) const; + 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); + const disasm_insn_t* lookup(insn_t insn) const; }; #endif