adds initial version of intruction cache
This commit is contained in:
parent
047e2e12b0
commit
dd937710a7
@ -38,10 +38,13 @@
|
||||
#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>
|
||||
@ -255,6 +258,11 @@ private:
|
||||
return iss::Err;
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
struct translation_buffer {
|
||||
std::vector<std::tuple<opcode_e, uint64_t, uint32_t>> entries;
|
||||
} tb;
|
||||
std::unordered_map<uint64_t, translation_buffer> tb_lut;
|
||||
};
|
||||
|
||||
template <typename CODE_WORD> void debug_fn(CODE_WORD insn) {
|
||||
@ -312,27 +320,8 @@ 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);
|
||||
|
||||
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
|
||||
auto exec = [this, PC, NEXT_PC](opcode_e inst_id, uint64_t pc, uint32_t instr) {
|
||||
// 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{
|
||||
@ -345,7 +334,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -372,7 +361,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -399,7 +388,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -436,7 +425,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -474,7 +463,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -510,7 +499,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -546,7 +535,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -582,7 +571,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -618,7 +607,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -654,7 +643,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -690,7 +679,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -722,7 +711,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -754,7 +743,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -786,7 +775,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -818,7 +807,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -850,7 +839,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -878,7 +867,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -906,7 +895,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -934,7 +923,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -962,7 +951,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -990,7 +979,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1018,7 +1007,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1046,7 +1035,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1074,7 +1063,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1102,7 +1091,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1130,7 +1119,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1158,7 +1147,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1186,7 +1175,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1214,7 +1203,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1242,7 +1231,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1270,7 +1259,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1298,7 +1287,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1326,7 +1315,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1354,7 +1343,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1382,7 +1371,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1410,7 +1399,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1438,7 +1427,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1468,7 +1457,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -1485,7 +1474,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -1501,7 +1490,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -1517,7 +1506,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -1533,7 +1522,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -1553,7 +1542,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1591,7 +1580,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1627,7 +1616,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1663,7 +1652,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1696,7 +1685,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1731,7 +1720,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1766,7 +1755,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -1787,7 +1776,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1816,7 +1805,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1845,7 +1834,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1874,7 +1863,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1903,7 +1892,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1944,7 +1933,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -1979,7 +1968,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2022,7 +2011,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2056,7 +2045,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2082,7 +2071,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2106,7 +2095,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2128,7 +2117,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2153,7 +2142,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -2170,7 +2159,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2192,7 +2181,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2219,7 +2208,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2243,7 +2232,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2266,7 +2255,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -2285,7 +2274,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2305,7 +2294,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2332,7 +2321,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2352,7 +2341,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2372,7 +2361,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2392,7 +2381,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2412,7 +2401,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2431,7 +2420,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -2451,7 +2440,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2474,7 +2463,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2497,7 +2486,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2524,7 +2513,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2552,7 +2541,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2578,7 +2567,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2602,7 +2591,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -2621,7 +2610,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2647,7 +2636,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2673,7 +2662,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -2692,7 +2681,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
|
||||
@ -2716,7 +2705,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.val, mnemonic);
|
||||
this->core.disass_output(pc, mnemonic);
|
||||
}
|
||||
// used registers
|
||||
// calculate next pc value
|
||||
@ -2739,16 +2728,54 @@ 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(trap_state!=0){
|
||||
if(this->core.reg.trap_state!=0){
|
||||
//In case of Instruction address misaligned (cause = 0 and trapid = 0) need the targeted addr (in tval)
|
||||
auto mcause = (trap_state>>16) & 0xff;
|
||||
super::core.enter_trap(trap_state, pc.val, mcause ? instr:tval);
|
||||
auto mcause = (this->core.reg.trap_state>>16) & 0xff;
|
||||
super::core.enter_trap(this->core.reg.trap_state, pc, mcause ? instr:tval);
|
||||
} else {
|
||||
icount++;
|
||||
instret++;
|
||||
this->core.reg.icount++;
|
||||
this->core.reg.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++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user