|
|
|
@ -38,17 +38,14 @@
|
|
|
|
|
#include <iss/iss.h>
|
|
|
|
|
#include <iss/interp/vm_base.h>
|
|
|
|
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <util/logging.h>
|
|
|
|
|
#include <boost/coroutine2/all.hpp>
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <exception>
|
|
|
|
|
#include <utility>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <iss/instruction_decoder.h>
|
|
|
|
|
#include <absl/container/flat_hash_map.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef FMT_HEADER_ONLY
|
|
|
|
|
#define FMT_HEADER_ONLY
|
|
|
|
@ -258,11 +255,6 @@ private:
|
|
|
|
|
return iss::Err;
|
|
|
|
|
return iss::Ok;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct translation_buffer {
|
|
|
|
|
std::vector<std::tuple<opcode_e, uint64_t, uint32_t>> entries;
|
|
|
|
|
} tb;
|
|
|
|
|
absl::flat_hash_map<uint64_t, translation_buffer> tb_lut;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename CODE_WORD> void debug_fn(CODE_WORD insn) {
|
|
|
|
@ -320,8 +312,27 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto& instr = this->core.reg.instruction;
|
|
|
|
|
// we fetch at max 4 byte, alignment is 2
|
|
|
|
|
auto *const data = reinterpret_cast<uint8_t*>(&instr);
|
|
|
|
|
auto exec = [this, PC, NEXT_PC](opcode_e inst_id, uint64_t pc, uint32_t instr) {
|
|
|
|
|
// pre execution stuff
|
|
|
|
|
|
|
|
|
|
while(!this->core.should_stop() &&
|
|
|
|
|
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
|
|
|
|
|
!(is_fcount_limit_enabled(cond) && fetch_count >= count_limit)){
|
|
|
|
|
if(this->debugging_enabled())
|
|
|
|
|
this->tgt_adapter->check_continue(*PC);
|
|
|
|
|
pc.val=*PC;
|
|
|
|
|
if(fetch_ins(pc, data)!=iss::Ok){
|
|
|
|
|
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
|
|
|
|
|
process_spawn_blocks();
|
|
|
|
|
if(this->sync_exec && POST_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
|
|
|
|
|
pc.val = super::core.enter_trap(arch::traits<ARCH>::RV_CAUSE_FETCH_ACCESS<<16, pc.val, 0);
|
|
|
|
|
} else {
|
|
|
|
|
if (is_jump_to_self_enabled(cond) &&
|
|
|
|
|
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
|
|
|
|
uint32_t inst_index = instr_decoder.decode_instr(instr);
|
|
|
|
|
opcode_e inst_id = arch::traits<ARCH>::opcode_e::MAX_OPCODE;;
|
|
|
|
|
if(inst_index <instr_descr.size())
|
|
|
|
|
inst_id = instr_descr[inst_index].op;
|
|
|
|
|
|
|
|
|
|
// pre execution stuff
|
|
|
|
|
this->core.reg.last_branch = 0;
|
|
|
|
|
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
|
|
|
|
|
try{
|
|
|
|
@ -334,7 +345,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -361,7 +372,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -388,7 +399,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -425,7 +436,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -463,7 +474,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -499,7 +510,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -535,7 +546,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -571,7 +582,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -607,7 +618,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -643,7 +654,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -679,7 +690,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -711,7 +722,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -743,7 +754,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -775,7 +786,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -807,7 +818,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -839,7 +850,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"),
|
|
|
|
|
fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -867,7 +878,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"),
|
|
|
|
|
fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -895,7 +906,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"),
|
|
|
|
|
fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -923,7 +934,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -951,7 +962,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -979,7 +990,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1007,7 +1018,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1035,7 +1046,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1063,7 +1074,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1091,7 +1102,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1119,7 +1130,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1147,7 +1158,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1175,7 +1186,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1203,7 +1214,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1231,7 +1242,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1259,7 +1270,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1287,7 +1298,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1315,7 +1326,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1343,7 +1354,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1371,7 +1382,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1399,7 +1410,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1427,7 +1438,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1457,7 +1468,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {pred}, {succ} ({fm} , {rs1}, {rd})", fmt::arg("mnemonic", "fence"),
|
|
|
|
|
fmt::arg("pred", pred), fmt::arg("succ", succ), fmt::arg("fm", fm), fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -1474,7 +1485,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = "ecall";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -1490,7 +1501,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = "ebreak";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -1506,7 +1517,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = "mret";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -1522,7 +1533,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = "wfi";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -1542,7 +1553,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1580,7 +1591,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1616,7 +1627,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1652,7 +1663,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1685,7 +1696,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1720,7 +1731,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1755,7 +1766,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {rd}, {imm}", fmt::arg("mnemonic", "fence_i"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -1776,7 +1787,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1805,7 +1816,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1834,7 +1845,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1863,7 +1874,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1892,7 +1903,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1933,7 +1944,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -1968,7 +1979,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2011,7 +2022,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2045,7 +2056,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"),
|
|
|
|
|
fmt::arg("rd", name(8+rd)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2071,7 +2082,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.lw"),
|
|
|
|
|
fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2095,7 +2106,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.sw"),
|
|
|
|
|
fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2117,7 +2128,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2142,7 +2153,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = "c.nop";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -2159,7 +2170,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"),
|
|
|
|
|
fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2181,7 +2192,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2208,7 +2219,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2232,7 +2243,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {nzimm:#05x}", fmt::arg("mnemonic", "c.addi16sp"),
|
|
|
|
|
fmt::arg("nzimm", nzimm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2255,7 +2266,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = ".reserved_clui";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -2274,7 +2285,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"),
|
|
|
|
|
fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2294,7 +2305,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"),
|
|
|
|
|
fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2321,7 +2332,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"),
|
|
|
|
|
fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2341,7 +2352,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"),
|
|
|
|
|
fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2361,7 +2372,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"),
|
|
|
|
|
fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2381,7 +2392,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"),
|
|
|
|
|
fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2401,7 +2412,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"),
|
|
|
|
|
fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2420,7 +2431,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"),
|
|
|
|
|
fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -2440,7 +2451,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"),
|
|
|
|
|
fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2463,7 +2474,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"),
|
|
|
|
|
fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2486,7 +2497,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}, {nzuimm}", fmt::arg("mnemonic", "c.slli"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)), fmt::arg("nzuimm", nzuimm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2513,7 +2524,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2541,7 +2552,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2567,7 +2578,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2591,7 +2602,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = ".reserved_cmv";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -2610,7 +2621,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"),
|
|
|
|
|
fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2636,7 +2647,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"),
|
|
|
|
|
fmt::arg("rs1", name(rs1)));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2662,7 +2673,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = "c.ebreak";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -2681,7 +2692,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
auto mnemonic = fmt::format(
|
|
|
|
|
"{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "c.swsp"),
|
|
|
|
|
fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm));
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
|
|
|
@ -2705,7 +2716,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
/* generate console output when executing the command */
|
|
|
|
|
//No disass specified, using instruction name
|
|
|
|
|
std::string mnemonic = "dii";
|
|
|
|
|
this->core.disass_output(pc, mnemonic);
|
|
|
|
|
this->core.disass_output(pc.val, mnemonic);
|
|
|
|
|
}
|
|
|
|
|
// used registers
|
|
|
|
|
// calculate next pc value
|
|
|
|
@ -2728,54 +2739,16 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|
|
|
|
// if(!this->core.reg.trap_state) // update trap state if there is a pending interrupt
|
|
|
|
|
// this->core.reg.trap_state = this->core.reg.pending_trap;
|
|
|
|
|
// trap check
|
|
|
|
|
if(this->core.reg.trap_state!=0){
|
|
|
|
|
if(trap_state!=0){
|
|
|
|
|
//In case of Instruction address misaligned (cause = 0 and trapid = 0) need the targeted addr (in tval)
|
|
|
|
|
auto mcause = (this->core.reg.trap_state>>16) & 0xff;
|
|
|
|
|
super::core.enter_trap(this->core.reg.trap_state, pc, mcause ? instr:tval);
|
|
|
|
|
auto mcause = (trap_state>>16) & 0xff;
|
|
|
|
|
super::core.enter_trap(trap_state, pc.val, mcause ? instr:tval);
|
|
|
|
|
} else {
|
|
|
|
|
this->core.reg.icount++;
|
|
|
|
|
this->core.reg.instret++;
|
|
|
|
|
icount++;
|
|
|
|
|
instret++;
|
|
|
|
|
}
|
|
|
|
|
*PC = *NEXT_PC;
|
|
|
|
|
this->core.reg.trap_state = this->core.reg.pending_trap;
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
while(!this->core.should_stop() &&
|
|
|
|
|
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
|
|
|
|
|
!(is_fcount_limit_enabled(cond) && fetch_count >= count_limit)){
|
|
|
|
|
if(this->debugging_enabled())
|
|
|
|
|
this->tgt_adapter->check_continue(*PC);
|
|
|
|
|
pc.val=*PC;
|
|
|
|
|
auto current_tb = tb_lut.find(pc.val);
|
|
|
|
|
if(current_tb==tb_lut.end()) {
|
|
|
|
|
auto res = tb_lut.insert(std::make_pair(pc.val,translation_buffer{}));
|
|
|
|
|
if(!res.second)
|
|
|
|
|
throw std::runtime_error("");
|
|
|
|
|
current_tb=res.first;
|
|
|
|
|
do {
|
|
|
|
|
if(fetch_ins(pc, data)!=iss::Ok){
|
|
|
|
|
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
|
|
|
|
|
process_spawn_blocks();
|
|
|
|
|
if(this->sync_exec && POST_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
|
|
|
|
|
pc.val = super::core.enter_trap(arch::traits<ARCH>::RV_CAUSE_FETCH_ACCESS<<16, pc.val, 0);
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
if (is_jump_to_self_enabled(cond) &&
|
|
|
|
|
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
|
|
|
|
uint32_t inst_index = instr_decoder.decode_instr(instr);
|
|
|
|
|
opcode_e inst_id = arch::traits<ARCH>::opcode_e::MAX_OPCODE;;
|
|
|
|
|
if(inst_index <instr_descr.size())
|
|
|
|
|
inst_id = instr_descr[inst_index].op;
|
|
|
|
|
if(is_jump_to_self_enabled(cond) &&
|
|
|
|
|
inst_id==arch::traits<ARCH>::opcode_e::JAL && !bit_sub<7, 25>(instr) ||
|
|
|
|
|
inst_id == arch::traits<ARCH>::opcode_e::C__J && !bit_sub<2, 11>(instr))
|
|
|
|
|
throw simulation_stopped(0);
|
|
|
|
|
exec(inst_id, pc.val, instr);
|
|
|
|
|
}
|
|
|
|
|
} while(this->core.reg.last_branch==0);
|
|
|
|
|
} else {
|
|
|
|
|
for(auto& e:current_tb->second.entries)
|
|
|
|
|
exec(std::get<0>(e), std::get<1>(e), std::get<2>(e));
|
|
|
|
|
}
|
|
|
|
|
fetch_count++;
|
|
|
|
|
cycle++;
|
|
|
|
|