URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Subversion Repositories riscv_vhdl
[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_fnc_plugin/] [srcproc/] [srcproc.cpp] - Rev 5
Compare with Previous | Blame | View Log
/** * @file * @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. * @author Sergey Khabarov - sergeykhbr@gmail.com * @brief Source code processor class declaration. */ #include "srcproc.h" #include <iostream> #include <riscv-isa.h> namespace debugger { /** Class registration in the Core */ enum ESymbInfo { SymbInfo_Name, SymbInfo_Address, SymbInfo_Total, }; const char *const *RN = IREGS_NAMES; int opcode_0x00(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x03(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x04(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x05(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x06(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x08(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x0C(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x0D(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x0E(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x18(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x19(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x1B(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int opcode_0x1C(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment); int C_ADDI16SP_LUI(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_ADDI4SPN(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_BEQZ(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_BNEZ(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_J(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_JAL_ADDIW(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_JR_MV_EBREAK_JALR_ADD(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_LD(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_LI(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_LDSP(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_LW(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_LWSP(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_MATH(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_NOP_ADDI(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_SD(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_SDSP(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_SLLI(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_SW(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); int C_SWSP(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment); RiscvSourceService::RiscvSourceService(const char *name) : IService(name) { registerInterface(static_cast<ISourceCode *>(this)); memset(tblOpcode1_, 0, sizeof(tblOpcode1_)); tblOpcode1_[0x00] = &opcode_0x00; tblOpcode1_[0x03] = &opcode_0x03; tblOpcode1_[0x04] = &opcode_0x04; tblOpcode1_[0x05] = &opcode_0x05; tblOpcode1_[0x06] = &opcode_0x06; tblOpcode1_[0x08] = &opcode_0x08; tblOpcode1_[0x0C] = &opcode_0x0C; tblOpcode1_[0x0D] = &opcode_0x0D; tblOpcode1_[0x0E] = &opcode_0x0E; tblOpcode1_[0x18] = &opcode_0x18; tblOpcode1_[0x19] = &opcode_0x19; tblOpcode1_[0x1B] = &opcode_0x1B; tblOpcode1_[0x1C] = &opcode_0x1C; memset(tblCompressed_, 0, sizeof(tblCompressed_)); // page 82, table 12.5 " RISC-V spec. v2.2" // Compute index as hash = {[15:13],[1:0]} tblCompressed_[0x00] = &C_ADDI4SPN; tblCompressed_[0x01] = &C_NOP_ADDI; tblCompressed_[0x02] = &C_SLLI; tblCompressed_[0x05] = &C_JAL_ADDIW; tblCompressed_[0x08] = &C_LW; tblCompressed_[0x09] = &C_LI; tblCompressed_[0x0A] = &C_LWSP; tblCompressed_[0x0C] = &C_LD; tblCompressed_[0x0D] = &C_ADDI16SP_LUI; tblCompressed_[0x0E] = &C_LDSP; tblCompressed_[0x11] = &C_MATH; tblCompressed_[0x12] = &C_JR_MV_EBREAK_JALR_ADD; tblCompressed_[0x15] = &C_J; tblCompressed_[0x18] = &C_SW; tblCompressed_[0x19] = &C_BEQZ; tblCompressed_[0x1A] = &C_SWSP; tblCompressed_[0x1C] = &C_SD; tblCompressed_[0x1D] = &C_BNEZ; tblCompressed_[0x1E] = &C_SDSP; brList_.make_list(0); symbolListSortByName_.make_list(0); symbolListSortByAddr_.make_list(0); } RiscvSourceService::~RiscvSourceService() { } void RiscvSourceService::postinitService() { } void RiscvSourceService::addFileSymbol(const char *name, uint64_t addr, int sz) { AttributeType symb(Attr_List); symb.make_list(Symbol_Total); symb[Symbol_Name].make_string(name); symb[Symbol_Addr].make_uint64(addr); symb[Symbol_Size].make_int64(sz); symbolListSortByName_.add_to_list(&symb); symbolListSortByName_.sort(Symbol_Name); symbolListSortByAddr_.add_to_list(&symb); symbolListSortByAddr_.sort(Symbol_Addr); } void RiscvSourceService::addFunctionSymbol(const char *name, uint64_t addr, int sz) { addFileSymbol(name, addr, sz); } void RiscvSourceService::addDataSymbol(const char *name, uint64_t addr, int sz) { addFileSymbol(name, addr, sz); } void RiscvSourceService::clearSymbols() { symbolListSortByName_.make_list(0); symbolListSortByAddr_.make_list(0); } void RiscvSourceService::addSymbols(AttributeType *list) { for (unsigned i = 0; i < list->size(); i++) { AttributeType &item = (*list)[i]; symbolListSortByName_.add_to_list(&item); symbolListSortByAddr_.add_to_list(&item); } symbolListSortByName_.sort(Symbol_Name); symbolListSortByAddr_.sort(Symbol_Addr); } void RiscvSourceService::addressToSymbol(uint64_t addr, AttributeType *info) { uint64_t sadr, send; int sz = static_cast<int>(symbolListSortByAddr_.size()); info->make_list(SymbInfo_Total); (*info)[SymbInfo_Name].make_string(""); (*info)[SymbInfo_Address].make_uint64(0); if (sz == 0) { return; } sadr = symbolListSortByAddr_[0u][Symbol_Addr].to_uint64(); if (addr < sadr) { return; } bool search = true; int dist, pos = sz / 2; dist = pos; while (search) { AttributeType &symb = symbolListSortByAddr_[pos]; sadr = symb[Symbol_Addr].to_uint64(); if (pos < static_cast<int>(symbolListSortByAddr_.size()) - 1) { send = symbolListSortByAddr_[pos + 1][Symbol_Addr].to_uint64(); } else { send = sadr + symb[Symbol_Size].to_uint64(); } if (sadr <= addr && addr < send) { (*info)[SymbInfo_Name] = symb[Symbol_Name]; (*info)[SymbInfo_Address].make_uint64(addr - sadr); return; } if (addr < sadr) { if (dist == 0 || pos == 0) { search = false; } else if (dist == 1) { dist = 0; pos--; } else { int incr = dist / 2; pos -= incr; dist = (dist / 2) + (dist & 0x1); if (pos < 0) { pos = 0; } } } else { if (dist == 0 || pos == (sz - 1)) { search = false; } else if (dist == 1) { dist = 0; pos++; } else { int incr = dist / 2; pos += incr; dist = (dist / 2) + (dist & 0x1); if (pos >= sz) { pos = sz - 1; } } } } } int RiscvSourceService::symbol2Address(const char *name, uint64_t *addr) { for (unsigned i = 0; i < symbolListSortByName_.size(); i++) { AttributeType &item = symbolListSortByName_[i]; if (item[Symbol_Name].is_equal(name)) { *addr = item[Symbol_Addr].to_uint64(); return 0; } } return -1; } void RiscvSourceService::registerBreakpoint(uint64_t addr, uint64_t flags, uint64_t instr) { AttributeType item; item.make_list(BrkList_Total); item[BrkList_address].make_uint64(addr); item[BrkList_flags].make_uint64(flags); item[BrkList_instr].make_uint64(instr); bool not_found = true; for (unsigned i = 0; i < brList_.size(); i++) { AttributeType &br = brList_[i]; if (addr == br[BrkList_address].to_uint64()) { not_found = false; } } if (not_found) { brList_.add_to_list(&item); } } int RiscvSourceService::unregisterBreakpoint(uint64_t addr, uint64_t *flags, uint64_t *instr) { for (unsigned i = 0; i < brList_.size(); i++) { AttributeType &br = brList_[i]; if (addr == br[BrkList_address].to_uint64()) { *flags = br[BrkList_flags].to_uint64(); *instr = br[BrkList_instr].to_uint64(); brList_.remove_from_list(i); return 0; } } return 1; } void RiscvSourceService::getBreakpointList(AttributeType *list) { if (!list->is_list() || list->size() != brList_.size()) { list->make_list(brList_.size()); } for (unsigned i = 0; i < brList_.size(); i++) { AttributeType &item = (*list)[i]; AttributeType &br = brList_[i]; if (!item.is_list() || item.size() != 3) { item.make_list(BrkList_Total); } item[BrkList_address] = br[BrkList_address]; item[BrkList_flags] = br[BrkList_flags]; item[BrkList_instr] = br[BrkList_instr]; } } bool RiscvSourceService::isBreakpoint(uint64_t addr, AttributeType *outbr) { for (unsigned i = 0; i < brList_.size(); i++) { uint64_t bradr = brList_[i][BrkList_address].to_uint64(); if (addr == bradr) { *outbr = brList_[i]; return true; } } return false; } int RiscvSourceService::disasm(uint64_t pc, uint8_t *data, int offset, AttributeType *mnemonic, AttributeType *comment) { int oplen; if ((data[offset] & 0x3) < 3) { Reg16Type val; uint32_t hash; val.word = *reinterpret_cast<uint16_t*>(&data[offset]); hash = ((val.word >> 11) & 0x1C) | (val.word & 0x3); oplen = 2; if (tblCompressed_[hash]) { return tblCompressed_[hash](static_cast<ISourceCode *>(this), pc + static_cast<uint64_t>(offset), val, mnemonic, comment); } } else if ((data[offset] & 0x3) == 0x3) { uint32_t val = *reinterpret_cast<uint32_t*>(&data[offset]); uint32_t opcode1 = (val >> 2) & 0x1f; oplen = 4; if (tblOpcode1_[opcode1]) { return tblOpcode1_[opcode1](static_cast<ISourceCode *>(this), pc + static_cast<uint64_t>(offset), val, mnemonic, comment); } } mnemonic->make_string("unimpl"); comment->make_string(""); return oplen; } void RiscvSourceService::disasm(uint64_t pc, AttributeType *idata, AttributeType *asmlist) { asmlist->make_list(0); if (!idata->is_data()) { return; } uint8_t *data = idata->data(); AttributeType asm_item, symb_item, info, brpoint; asm_item.make_list(ASM_Total); symb_item.make_list(3); asm_item[ASM_list_type].make_int64(AsmList_disasm); symb_item[ASM_list_type].make_int64(AsmList_symbol); uint64_t off = 0; Reg64Type code; int codesz; while (static_cast<unsigned>(off) < idata->size()) { code.val = *reinterpret_cast<uint32_t*>(&data[off]); addressToSymbol(pc + off, &info); if (info[SymbInfo_Name].size() != 0 && info[SymbInfo_Address].to_int() == 0) { symb_item[1].make_uint64(pc + off); symb_item[2].make_string(info[SymbInfo_Name].to_string()); asmlist->add_to_list(&symb_item); } asm_item[ASM_addrline].make_uint64(pc + off); asm_item[ASM_breakpoint].make_boolean(false); asm_item[ASM_label].make_string(""); if (isBreakpoint(pc + off, &brpoint)) { asm_item[ASM_breakpoint].make_boolean(true); if (!(brpoint[BrkList_flags].to_uint64() & BreakFlag_HW)) { code.val = brpoint[BrkList_instr].to_uint32(); } } codesz = disasm(pc + off, code.buf, 0, &asm_item[ASM_mnemonic], &asm_item[ASM_comment]); #if 1 uint64_t swap = code.val; if (codesz == 2) { swap = code.buf16[0]; } #else uint64_t swap = 0; for (int i = 0; i < codesz; i++) { swap = (swap << 8) | code.buf[i]; } #endif asm_item[ASM_code].make_uint64(swap); asm_item[ASM_codesize].make_uint64(codesz); asmlist->add_to_list(&asm_item); off += codesz; } } int opcode_0x00(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_I_type i; int32_t imm; i.value = code; imm = static_cast<int32_t>(code) >> 20; switch (i.bits.funct3) { case 0: RISCV_sprintf(tstr, sizeof(tstr), "lb %s,%d(%s)", RN[i.bits.rd], imm, RN[i.bits.rs1]); break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "lh %s,%d(%s)", RN[i.bits.rd], imm, RN[i.bits.rs1]); break; case 2: RISCV_sprintf(tstr, sizeof(tstr), "lw %s,%d(%s)", RN[i.bits.rd], imm, RN[i.bits.rs1]); break; case 3: RISCV_sprintf(tstr, sizeof(tstr), "ld %s,%d(%s)", RN[i.bits.rd], imm, RN[i.bits.rs1]); break; case 4: RISCV_sprintf(tstr, sizeof(tstr), "lbu %s,%d(%s)", RN[i.bits.rd], imm, RN[i.bits.rs1]); break; case 5: RISCV_sprintf(tstr, sizeof(tstr), "lhu %s,%d(%s)", RN[i.bits.rd], imm, RN[i.bits.rs1]); break; case 6: RISCV_sprintf(tstr, sizeof(tstr), "lwu %s,%d(%s)", RN[i.bits.rd], imm, RN[i.bits.rs1]); break; default:; } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x03(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_R_type r; r.value = code; switch (r.bits.funct3) { case 0: RISCV_sprintf(tstr, sizeof(tstr), "%s", "fence"); break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "%s", "fence_i"); break; default:; } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x04(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_I_type i; int32_t imm; i.value = code; imm = static_cast<int32_t>(code) >> 20; switch (i.bits.funct3) { case 0: if (imm == 0) { RISCV_sprintf(tstr, sizeof(tstr), "mv %s,%s", RN[i.bits.rd], RN[i.bits.rs1]); } else if (i.bits.rs1 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "li %s,%d", RN[i.bits.rd], imm); } else { RISCV_sprintf(tstr, sizeof(tstr), "addi %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); } break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "slli %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); break; case 2: RISCV_sprintf(tstr, sizeof(tstr), "slti %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); break; case 3: RISCV_sprintf(tstr, sizeof(tstr), "sltiu %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); break; case 4: RISCV_sprintf(tstr, sizeof(tstr), "xori %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); break; case 5: if ((code >> 26) == 0) { RISCV_sprintf(tstr, sizeof(tstr), "srli %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); } else if ((code >> 26) == 0x20) { RISCV_sprintf(tstr, sizeof(tstr), "srai %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); } break; case 6: RISCV_sprintf(tstr, sizeof(tstr), "ori %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); break; case 7: RISCV_sprintf(tstr, sizeof(tstr), "andi %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); break; default:; } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x05(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_U_type u; uint64_t imm64; u.value = code; imm64 = u.bits.imm31_12 << 12; if (imm64 & (1LL << 31)) { imm64 |= EXT_SIGN_32; } RISCV_sprintf(tstr, sizeof(tstr), "auipc %s,0x%" RV_PRI64 "x", RN[u.bits.rd], imm64); mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x06(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_I_type i; int32_t imm; i.value = code; imm = static_cast<int32_t>(code) >> 20; switch (i.bits.funct3) { case 0: RISCV_sprintf(tstr, sizeof(tstr), "addiw %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "slliw %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); break; case 5: if ((code >> 25) == 0) { RISCV_sprintf(tstr, sizeof(tstr), "srliw %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); } else if ((code >> 25) == 0x20) { RISCV_sprintf(tstr, sizeof(tstr), "sraiw %s,%s,%d", RN[i.bits.rd], RN[i.bits.rs1], imm); } break; default:; } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x08(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_S_type s; int32_t imm; s.value = code; imm = (s.bits.imm11_5 << 5) | s.bits.imm4_0; if (imm & 0x800) { imm |= EXT_SIGN_12; } switch (s.bits.funct3) { case 0: RISCV_sprintf(tstr, sizeof(tstr), "sb %s,%d(%s)", RN[s.bits.rs2], imm, RN[s.bits.rs1]); break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "sh %s,%d(%s)", RN[s.bits.rs2], imm, RN[s.bits.rs1]); break; case 2: RISCV_sprintf(tstr, sizeof(tstr), "sw %s,%d(%s)", RN[s.bits.rs2], imm, RN[s.bits.rs1]); break; case 3: RISCV_sprintf(tstr, sizeof(tstr), "sd %s,%d(%s)", RN[s.bits.rs2], imm, RN[s.bits.rs1]); break; default:; } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x0C(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_R_type r; r.value = code; switch (r.bits.funct3) { case 0: if (r.bits.funct7 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "add %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "mul %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 0x20) { RISCV_sprintf(tstr, sizeof(tstr), "sub %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "sll %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); break; case 2: RISCV_sprintf(tstr, sizeof(tstr), "slt %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); break; case 3: RISCV_sprintf(tstr, sizeof(tstr), "sltu %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); break; case 4: if (r.bits.funct7 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "xor %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "div %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; case 5: if (r.bits.funct7 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "srl %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "divu %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 0x20) { RISCV_sprintf(tstr, sizeof(tstr), "sra %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; case 6: if (r.bits.funct7 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "or %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "rem %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; case 7: if (r.bits.funct7 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "and %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "remu %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; default:; } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x0D(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_U_type u; u.value = code; RISCV_sprintf(tstr, sizeof(tstr), "lui %s,0x%x", RN[u.bits.rd], u.bits.imm31_12); mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x0E(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_R_type r; r.value = code; switch (r.bits.funct3) { case 0: if (r.bits.funct7 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "addw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "mulw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 0x20) { RISCV_sprintf(tstr, sizeof(tstr), "subw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "sllw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); break; case 4: if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "divw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; case 5: if (r.bits.funct7 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "srlw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "divuw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } else if (r.bits.funct7 == 0x20) { RISCV_sprintf(tstr, sizeof(tstr), "sraw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; case 6: if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "remw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; case 7: if (r.bits.funct7 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "remuw %s,%s,%s", RN[r.bits.rd], RN[r.bits.rs1], RN[r.bits.rs2]); } break; default:; } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x18(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_SB_type sb; uint64_t imm64; sb.value = code; imm64 = (sb.bits.imm12 << 12) | (sb.bits.imm11 << 11) | (sb.bits.imm10_5 << 5) | (sb.bits.imm4_1 << 1); if (sb.bits.imm12) { imm64 |= EXT_SIGN_12; } imm64 += pc; switch (sb.bits.funct3) { case 0: if (sb.bits.rs2 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "beqz %s,%08" RV_PRI64 "x", RN[sb.bits.rs1], imm64); } else { RISCV_sprintf(tstr, sizeof(tstr), "beq %s,%s,%08" RV_PRI64 "x", RN[sb.bits.rs1], RN[sb.bits.rs2], imm64); } break; case 1: if (sb.bits.rs2 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "bnez %s,%08" RV_PRI64 "x", RN[sb.bits.rs1], imm64); } else { RISCV_sprintf(tstr, sizeof(tstr), "bne %s,%s,%08" RV_PRI64 "x", RN[sb.bits.rs1], RN[sb.bits.rs2], imm64); } break; case 4: if (sb.bits.rs2 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "bltz %s,%08" RV_PRI64 "x", RN[sb.bits.rs1], imm64); } else { RISCV_sprintf(tstr, sizeof(tstr), "blt %s,%s,%08" RV_PRI64 "x", RN[sb.bits.rs1], RN[sb.bits.rs2], imm64); } break; case 5: if (sb.bits.rs2 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "bgez %s,%08" RV_PRI64 "x", RN[sb.bits.rs1], imm64); } else { RISCV_sprintf(tstr, sizeof(tstr), "bge %s,%s,%08" RV_PRI64 "x", RN[sb.bits.rs1], RN[sb.bits.rs2], imm64); } break; case 6: if (sb.bits.rs2 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "bltuz %s,%08" RV_PRI64 "x", RN[sb.bits.rs1], imm64); } else { RISCV_sprintf(tstr, sizeof(tstr), "bltu %s,%s,%08" RV_PRI64 "x", RN[sb.bits.rs1], RN[sb.bits.rs2], imm64); } break; case 7: if (sb.bits.rs2 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "bgeuz %s,%08" RV_PRI64 "x", RN[sb.bits.rs1], imm64); } else { RISCV_sprintf(tstr, sizeof(tstr), "bgeu %s,%s,%08" RV_PRI64 "x", RN[sb.bits.rs1], RN[sb.bits.rs2], imm64); } break; default:; } if (isrc) { AttributeType info; isrc->addressToSymbol(imm64, &info); if (info[0u].size()) { if (info[1].to_uint32() == 0) { RISCV_sprintf(tcomm, sizeof(tcomm), "%s", info[0u].to_string()); } else { RISCV_sprintf(tcomm, sizeof(tcomm), "%s+%xh", info[0u].to_string(), info[1].to_uint32()); } } } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x19(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_I_type i; uint64_t imm64; i.value = code; imm64 = static_cast<int32_t>(code) >> 20; if (imm64 == 0) { if (i.bits.rs1 == Reg_ra) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "ret"); } else if (i.bits.rd == 0) { RISCV_sprintf(tstr, sizeof(tstr), "jr %s", RN[i.bits.rs1]); } else { RISCV_sprintf(tstr, sizeof(tstr), "jalr %s", RN[i.bits.rs1]); } } else { RISCV_sprintf(tstr, sizeof(tstr), "jalr %" RV_PRI64 "d,(%s)", imm64, RN[i.bits.rs1]); } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x1B(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_UJ_type uj; uint64_t imm64; uj.value = code; imm64 = 0; if (uj.bits.imm20) { imm64 = 0xfffffffffff00000LL; } imm64 |= (uj.bits.imm19_12 << 12); imm64 |= (uj.bits.imm11 << 11); imm64 |= (uj.bits.imm10_1 << 1); if (uj.bits.rd) { RISCV_sprintf(tstr, sizeof(tstr), "jal ra,%08" RV_PRI64 "x", pc + imm64); } else { RISCV_sprintf(tstr, sizeof(tstr), "j %08" RV_PRI64 "x", pc + imm64); } if (isrc) { AttributeType info; isrc->addressToSymbol(pc + imm64, &info); if (info[0u].size()) { if (info[1].to_uint32() == 0) { RISCV_sprintf(tcomm, sizeof(tcomm), "%s", info[0u].to_string()); } else { RISCV_sprintf(tcomm, sizeof(tcomm), "%s+%xh", info[0u].to_string(), info[1].to_uint32()); } } } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } int opcode_0x1C(ISourceCode *isrc, uint64_t pc, uint32_t code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_I_type i; uint32_t imm; i.value = code; imm = static_cast<int32_t>(code) >> 20; switch (i.bits.funct3) { case 0: if (code == 0x00000073) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "ecall"); } else if (code == 0x00100073) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "ebreak"); } else if (code == 0x00200073) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "uret"); } else if (code == 0x10200073) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "sret"); } else if (code == 0x20200073) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "hret"); } else if (code == 0x30200073) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "mret"); } break; case 1: if (i.bits.rd == 0) { RISCV_sprintf(tstr, sizeof(tstr), "csrw 0x%x,%s", imm, RN[i.bits.rs1]); } else { RISCV_sprintf(tstr, sizeof(tstr), "csrrw %s,0x%x,%s", RN[i.bits.rd], imm, RN[i.bits.rs1]); } break; case 2: if (i.bits.rs1 == 0) { // Read RISCV_sprintf(tstr, sizeof(tstr), "csrr %s,0x%x", RN[i.bits.rd], imm); } else if (i.bits.rd == 0) { // Set RISCV_sprintf(tstr, sizeof(tstr), "csrs 0x%x,%s", imm, RN[i.bits.rs1]); } else { // Read and set RISCV_sprintf(tstr, sizeof(tstr), "csrrs %s,0x%x,%s", RN[i.bits.rd], imm, RN[i.bits.rs1]); } break; case 3: if (i.bits.rd == 0) { RISCV_sprintf(tstr, sizeof(tstr), "csrc 0x%x,%s", imm, RN[i.bits.rs1]); } else { RISCV_sprintf(tstr, sizeof(tstr), "csrrc %s,0x%x,%s", RN[i.bits.rd], imm, RN[i.bits.rs1]); } break; case 5: if (i.bits.rd == 0) { RISCV_sprintf(tstr, sizeof(tstr), "csrwi 0x%x,0x%x", imm, i.bits.rs1); } else { RISCV_sprintf(tstr, sizeof(tstr), "csrrwi %s,0x%x,0x%x", RN[i.bits.rd], imm, i.bits.rs1); } break; case 6: if (i.bits.rd == 0) { RISCV_sprintf(tstr, sizeof(tstr), "csrsi 0x%x,0x%x", imm, i.bits.rs1); } else { RISCV_sprintf(tstr, sizeof(tstr), "csrrsi %s,0x%x,0x%x", RN[i.bits.rd], imm, i.bits.rs1); } break; case 7: if (i.bits.rd == 0) { RISCV_sprintf(tstr, sizeof(tstr), "csrci 0x%x,0x%x", imm, i.bits.rs1); } else { RISCV_sprintf(tstr, sizeof(tstr), "csrrci %s,0x%x,0x%x", RN[i.bits.rd], imm, i.bits.rs1); } break; default:; } mnemonic->make_string(tstr); comment->make_string(tcomm); return 4; } /** * C-extension disassembler */ int C_JR_MV_EBREAK_JALR_ADD(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_CR_type u; u.value = code.word; if (u.bits.funct4 == 0x8) { if (u.bits.rdrs1 && !u.bits.rs2) { if (u.bits.rdrs1 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "ret"); } else { RISCV_sprintf(tstr, sizeof(tstr), "jr %s", RN[u.bits.rdrs1]); } } else { RISCV_sprintf(tstr, sizeof(tstr), "mv %s,%s", RN[u.bits.rdrs1], RN[u.bits.rs2]); } } else { if (!u.bits.rdrs1 && !u.bits.rs2) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "ebreak"); } else if (u.bits.rdrs1 && !u.bits.rs2) { RISCV_sprintf(tstr, sizeof(tstr), "jalr ra,%s,0", RN[u.bits.rdrs1]); } else { RISCV_sprintf(tstr, sizeof(tstr), "add %s,%s,%s", RN[u.bits.rdrs1], RN[u.bits.rdrs1], RN[u.bits.rs2]); } } mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_NOP_ADDI(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CI_type u; u.value = code.word; uint64_t imm = u.bits.imm; if (u.bits.imm6) { imm |= EXT_SIGN_6; } if (u.value == 0x1) { RISCV_sprintf(tstr, sizeof(tstr), "%s", "nop"); } else { RISCV_sprintf(tstr, sizeof(tstr), "addi %s,%s,%" RV_PRI64 "d", RN[u.bits.rdrs], RN[u.bits.rdrs], imm); } mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_ADDI16SP_LUI(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CI_type u; u.value = code.word; if (u.spbits.sp == 0x2) { uint64_t imm = (u.spbits.imm8_7 << 3) | (u.spbits.imm6 << 2) | (u.spbits.imm5 << 1) | u.spbits.imm4; if (u.spbits.imm9) { imm |= EXT_SIGN_6; } imm <<= 4; RISCV_sprintf(tstr, sizeof(tstr), "addi sp,sp,%" RV_PRI64 "d", imm); } else { uint64_t imm = u.bits.imm; if (u.bits.imm6) { imm |= EXT_SIGN_6; } imm <<= 12; RISCV_sprintf(tstr, sizeof(tstr), "lui %s,0x%x", RN[u.bits.rdrs], static_cast<uint32_t>(imm)); } mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_ADDI4SPN(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimp"; char tcomm[128] = ""; ISA_CIW_type u; u.value = code.word; uint64_t imm = (u.bits.imm9_6 << 4) | (u.bits.imm5_4 << 2) | (u.bits.imm3 << 1) | u.bits.imm2; imm <<= 2; if (code.word) { RISCV_sprintf(tstr, sizeof(tstr), "addi %s,sp,%" RV_PRI64 "d", RN[8 + u.bits.rd], imm); } mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_JAL_ADDIW(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CI_type u; u.value = code.word; int64_t imm = u.bits.imm; if (u.bits.imm6) { imm |= EXT_SIGN_6; } // JAL is th RV32C only instruction RISCV_sprintf(tstr, sizeof(tstr), "addiw %s,%s,%" RV_PRI64 "d", RN[u.bits.rdrs], RN[u.bits.rdrs], imm); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_LD(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CL_type u; u.value = code.word; uint32_t off = (u.bits.imm27 << 4) | (u.bits.imm6 << 3) | u.bits.imm5_3; off <<= 3; RISCV_sprintf(tstr, sizeof(tstr), "ld %s,%d(%s)", RN[8 + u.bits.rd], off, RN[8 + u.bits.rs1]); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_LDSP(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CI_type u; u.value = code.word; uint32_t off = (u.ldspbits.off8_6 << 3) | (u.ldspbits.off5 << 2) | u.ldspbits.off4_3; off <<= 3; RISCV_sprintf(tstr, sizeof(tstr), "ld %s,%d(sp)", RN[u.ldspbits.rd], off); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_LI(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CI_type u; u.value = code.word; int64_t imm = u.bits.imm; if (u.bits.imm6) { imm |= EXT_SIGN_6; } RISCV_sprintf(tstr, sizeof(tstr), "li %s,%" RV_PRI64 "d", RN[u.bits.rdrs], imm); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_LW(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CL_type u; u.value = code.word; uint32_t off = (u.bits.imm6 << 4) | (u.bits.imm5_3 << 1) | u.bits.imm27; off <<= 2; RISCV_sprintf(tstr, sizeof(tstr), "lw %s,%d(%s)", RN[8 + u.bits.rd], off, RN[8 + u.bits.rs1]); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_LWSP(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CI_type u; u.value = code.word; uint32_t off = (u.lwspbits.off7_6 << 4) | (u.lwspbits.off5 << 3) | u.lwspbits.off4_2; off <<= 2; RISCV_sprintf(tstr, sizeof(tstr), "lw %s,%d(sp)", RN[u.lwspbits.rd], off); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_MATH(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128] = "unimpl"; char tcomm[128] = ""; ISA_CB_type u; u.value = code.word; uint32_t shamt = (u.shbits.shamt5 << 5) | u.shbits.shamt; uint32_t imm = (u.bits.off7_6 << 3) | (u.bits.off2_1 << 1) | u.bits.off5; if (u.bits.off4_3 == 0) { RISCV_sprintf(tstr, sizeof(tstr), "srli %s,%s,%d", RN[8 + u.shbits.rd], RN[8 + u.shbits.rd], shamt); } else if (u.bits.off4_3 == 1) { RISCV_sprintf(tstr, sizeof(tstr), "srai %s,%s,%d", RN[8 + u.shbits.rd], RN[8 + u.shbits.rd], shamt); } else if (u.bits.off4_3 == 2) { RISCV_sprintf(tstr, sizeof(tstr), "andi %s,%s,%d", RN[8 + u.shbits.rd], RN[8 + u.shbits.rd], imm); } else if (u.bits.off8 == 0) { ISA_CS_type u2; u2.value = code.word; switch (u.bits.off7_6) { case 0: RISCV_sprintf(tstr, sizeof(tstr), "sub %s,%s,%s", RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]); break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "xor %s,%s,%s", RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]); break; case 2: RISCV_sprintf(tstr, sizeof(tstr), "or %s,%s,%s", RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]); break; default: RISCV_sprintf(tstr, sizeof(tstr), "and %s,%s,%s", RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]); } } else { ISA_CS_type u2; u2.value = code.word; switch (u.bits.off7_6) { case 0: RISCV_sprintf(tstr, sizeof(tstr), "subw %s,%s,%s", RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]); break; case 1: RISCV_sprintf(tstr, sizeof(tstr), "addw %s,%s,%s", RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs1], RN[8 + u2.bits.rs2]); break; default:; } } mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_J(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CJ_type u; u.value = code.word; uint64_t off = (u.bits.off10 << 9) | (u.bits.off9_8 << 7) | (u.bits.off7 << 6) | (u.bits.off6 << 5) | (u.bits.off5 << 4) | (u.bits.off4 << 3) | u.bits.off3_1; off <<= 1; if (u.bits.off11) { off |= EXT_SIGN_11; } RISCV_sprintf(tstr, sizeof(tstr), "j %" RV_PRI64 "x", pc + off); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_SD(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CS_type u; u.value = code.word; uint32_t off = (u.bits.imm27 << 4) | (u.bits.imm6 << 3) | u.bits.imm5_3; off <<= 3; RISCV_sprintf(tstr, sizeof(tstr), "sd %s,%d(%s)", RN[8 + u.bits.rs2], off, RN[8 + u.bits.rs1]); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_SDSP(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CSS_type u; u.value = code.word; uint32_t off = (u.dbits.imm8_6 << 3) | u.dbits.imm5_3; off <<= 3; RISCV_sprintf(tstr, sizeof(tstr), "sd %s,%d(sp)", RN[u.dbits.rs2], off); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_SW(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CS_type u; u.value = code.word; uint32_t off = (u.bits.imm6 << 4) | (u.bits.imm5_3 << 1) | u.bits.imm27; off <<= 2; RISCV_sprintf(tstr, sizeof(tstr), "sw %s,%d(%s)", RN[8 + u.bits.rs2], off, RN[8 + u.bits.rs1]); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_SWSP(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CSS_type u; u.value = code.word; uint32_t off = (u.wbits.imm7_6 << 4) | u.wbits.imm5_2; off <<= 2; RISCV_sprintf(tstr, sizeof(tstr), "sw %s,%d(sp)", RN[u.dbits.rs2], off); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_BEQZ(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CB_type u; u.value = code.word; uint64_t imm = (u.bits.off7_6 << 5) | (u.bits.off5 << 4) | (u.bits.off4_3 << 2) | u.bits.off2_1; imm <<= 1; if (u.bits.off8) { imm |= EXT_SIGN_9; } RISCV_sprintf(tstr, sizeof(tstr), "beqz %s,%" RV_PRI64 "x", RN[8 + u.bits.rs1], pc + imm); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_BNEZ(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CB_type u; u.value = code.word; uint64_t imm = (u.bits.off7_6 << 5) | (u.bits.off5 << 4) | (u.bits.off4_3 << 2) | u.bits.off2_1; imm <<= 1; if (u.bits.off8) { imm |= EXT_SIGN_9; } RISCV_sprintf(tstr, sizeof(tstr), "bnez %s,%" RV_PRI64 "x", RN[8 + u.bits.rs1], pc + imm); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } int C_SLLI(ISourceCode *isrc, uint64_t pc, Reg16Type code, AttributeType *mnemonic, AttributeType *comment) { char tstr[128]; char tcomm[128] = ""; ISA_CB_type u; u.value = code.word; uint32_t shamt = (u.shbits.shamt5 << 5) | u.shbits.shamt; uint32_t idx = (u.shbits.funct2 << 3) | u.shbits.rd; RISCV_sprintf(tstr, sizeof(tstr), "slli %s,%s,%d", RN[idx], RN[idx], shamt); mnemonic->make_string(tstr); comment->make_string(tcomm); return 2; } } // namespace debugger