add code word access for ISS plugins

This commit is contained in:
Eyck Jentzsch 2022-04-25 14:18:19 +02:00
parent 477c530847
commit a92b84bef4
9 changed files with 42 additions and 33 deletions

View File

@ -1,6 +1,6 @@
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc" import "RV32I.core_desc"
import "CoreDSL-Instruction-Set-Description/RVM.core_desc" import "RVM.core_desc"
import "CoreDSL-Instruction-Set-Description/RVC.core_desc" import "RVC.core_desc"
Core TGC_C provides RV32I, Zicsr, Zifencei, RV32M, RV32IC { Core TGC_C provides RV32I, Zicsr, Zifencei, RV32M, RV32IC {
architectural_state { architectural_state {

View File

@ -33,7 +33,7 @@
def getRegisterSizes(){ def getRegisterSizes(){
def regs = registers.collect{it.size} def regs = registers.collect{it.size}
regs[-1]=64 // correct for NEXT_PC regs[-1]=64 // correct for NEXT_PC
regs+=[32, 32, 64, 64, 64] // append TRAP_STATE, PENDING_TRAP, ICOUNT, CYCLE, INSTRET regs+=[32, 32, 64, 64, 64, 32] // append TRAP_STATE, PENDING_TRAP, ICOUNT, CYCLE, INSTRET, INSTRUCTION
return regs return regs
} }
%> %>

View File

@ -37,7 +37,7 @@ def nativeTypeSize(int size){
} }
def getRegisterSizes(){ def getRegisterSizes(){
def regs = registers.collect{nativeTypeSize(it.size)} def regs = registers.collect{nativeTypeSize(it.size)}
regs+=[32,32, 64, 64, 64] // append TRAP_STATE, PENDING_TRAP, ICOUNT, CYCLE, INSTRET regs+=[32,32, 64, 64, 64, 32] // append TRAP_STATE, PENDING_TRAP, ICOUNT, CYCLE, INSTRET, INSTRUCTION
return regs return regs
} }
def getRegisterOffsets(){ def getRegisterOffsets(){
@ -96,7 +96,8 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
PENDING_TRAP, PENDING_TRAP,
ICOUNT, ICOUNT,
CYCLE, CYCLE,
INSTRET INSTRET,
INSTRUCTION
}; };
using reg_t = uint${addrDataWidth}_t; using reg_t = uint${addrDataWidth}_t;
@ -170,6 +171,7 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
uint32_t trap_state = 0, pending_trap = 0; uint32_t trap_state = 0, pending_trap = 0;
uint64_t icount = 0; uint64_t icount = 0;
uint64_t instret = 0; uint64_t instret = 0;
uint32_t instruction = 0;
uint32_t last_branch; uint32_t last_branch;
} reg; } reg;
#pragma pack(pop) #pragma pack(pop)

View File

@ -277,9 +277,6 @@ typename arch::traits<ARCH>::opcode_e vm_impl<ARCH>::decode_inst_id(code_word_t
template <typename ARCH> template <typename ARCH>
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){
// we fetch at max 4 byte, alignment is 2
code_word_t instr = 0;
auto *const data = (uint8_t *)&instr;
auto pc=start; auto pc=start;
auto* PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]); auto* PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
@ -287,6 +284,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
auto* icount = reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::ICOUNT]); auto* icount = reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::ICOUNT]);
auto* instret = reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::INSTRET]); auto* instret = reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::INSTRET]);
auto *const instruction = reinterpret_cast<code_word_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::INSTRUCTION]);
// we fetch at max 4 byte, alignment is 2
auto *const data = reinterpret_cast<uint8_t*>(instruction);
auto& instr = *instruction;
while(!this->core.should_stop() && while(!this->core.should_stop() &&
!(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){ !(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){

View File

@ -235,9 +235,11 @@ protected:
*/ */
const std::string core_type_name() const override { return traits<BASE>::core_type; } const std::string core_type_name() const override { return traits<BASE>::core_type; }
uint64_t get_pc() override { return arch.get_pc(); }; uint64_t get_pc() override { return arch.reg.PC; };
uint64_t get_next_pc() override { return arch.get_next_pc(); }; uint64_t get_next_pc() override { return arch.reg.NEXT_PC; };
uint64_t get_instr_word() override { return arch.reg.instruction; }
uint64_t get_instr_count() { return arch.reg.icount; } uint64_t get_instr_count() { return arch.reg.icount; }
@ -249,8 +251,6 @@ protected:
}; };
friend struct riscv_instrumentation_if; friend struct riscv_instrumentation_if;
addr_t get_pc() { return this->reg.PC; }
addr_t get_next_pc() { return this->reg.NEXT_PC; }
virtual iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data); virtual iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data);
virtual iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data); virtual iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data);

View File

@ -53,7 +53,7 @@ template <> struct traits<tgc_c> {
static constexpr std::array<const char*, 36> reg_aliases{ static constexpr std::array<const char*, 36> reg_aliases{
{"ZERO", "RA", "SP", "GP", "TP", "T0", "T1", "T2", "S0", "S1", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC", "NEXT_PC", "PRIV", "DPC"}}; {"ZERO", "RA", "SP", "GP", "TP", "T0", "T1", "T2", "S0", "S1", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC", "NEXT_PC", "PRIV", "DPC"}};
enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, RFS=32, INSTR_ALIGNMENT=2, XLEN=32, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, RFS=32, XLEN=32, CSR_SIZE=4096, INSTR_ALIGNMENT=2, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64};
constexpr static unsigned FP_REGS_SIZE = 0; constexpr static unsigned FP_REGS_SIZE = 0;
@ -63,7 +63,8 @@ template <> struct traits<tgc_c> {
PENDING_TRAP, PENDING_TRAP,
ICOUNT, ICOUNT,
CYCLE, CYCLE,
INSTRET INSTRET,
INSTRUCTION
}; };
using reg_t = uint32_t; using reg_t = uint32_t;
@ -76,11 +77,11 @@ template <> struct traits<tgc_c> {
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>; using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
static constexpr std::array<const uint32_t, 41> reg_bit_widths{ static constexpr std::array<const uint32_t, 42> reg_bit_widths{
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,8,32,32,32,64,64,64}}; {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,8,32,32,32,64,64,64,32}};
static constexpr std::array<const uint32_t, 41> reg_byte_offsets{ static constexpr std::array<const uint32_t, 42> reg_byte_offsets{
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,137,141,145,149,157,165}}; {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,137,141,145,149,157,165,173}};
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
@ -259,6 +260,7 @@ struct tgc_c: public arch_if {
uint32_t trap_state = 0, pending_trap = 0; uint32_t trap_state = 0, pending_trap = 0;
uint64_t icount = 0; uint64_t icount = 0;
uint64_t instret = 0; uint64_t instret = 0;
uint32_t instruction = 0;
uint32_t last_branch; uint32_t last_branch;
} reg; } reg;
#pragma pack(pop) #pragma pack(pop)

View File

@ -41,8 +41,8 @@ using namespace iss::arch;
constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc_c>::reg_names; constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc_c>::reg_names;
constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc_c>::reg_aliases; constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc_c>::reg_aliases;
constexpr std::array<const uint32_t, 41> iss::arch::traits<iss::arch::tgc_c>::reg_bit_widths; constexpr std::array<const uint32_t, 42> iss::arch::traits<iss::arch::tgc_c>::reg_bit_widths;
constexpr std::array<const uint32_t, 41> iss::arch::traits<iss::arch::tgc_c>::reg_byte_offsets; constexpr std::array<const uint32_t, 42> iss::arch::traits<iss::arch::tgc_c>::reg_byte_offsets;
tgc_c::tgc_c() { tgc_c::tgc_c() {
reg.icount = 0; reg.icount = 0;

View File

@ -1,6 +1,7 @@
#include <iss/arch_if.h> #include <iss/arch_if.h>
#include <iss/plugin/pctrace.h> #include <iss/plugin/pctrace.h>
#include <util/logging.h> #include <util/logging.h>
#include <util/ities.h>
#include <rapidjson/document.h> #include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h> #include <rapidjson/istreamwrapper.h>
#include "rapidjson/writer.h" #include "rapidjson/writer.h"
@ -123,7 +124,9 @@ void iss::plugin::cov::callback(instr_info_t iinfo, const exec_info& einfo) {
//source code for the full output //source code for the full output
auto delay = 0; auto delay = 0;
auto entry = delays[iinfo.instr_id]; size_t id = iinfo.instr_id;
auto entry = delays[id];
auto call = (id==2 || id==3) && bit_sub<7,5>(instr_if->get_instr_word())!=0;
bool taken = einfo.branch_taken; bool taken = einfo.branch_taken;
if (einfo.branch_taken) if (einfo.branch_taken)
delay = entry.taken; delay = entry.taken;

View File

@ -358,9 +358,6 @@ typename arch::traits<ARCH>::opcode_e vm_impl<ARCH>::decode_inst_id(code_word_t
template <typename ARCH> template <typename ARCH>
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){
// we fetch at max 4 byte, alignment is 2
code_word_t instr = 0;
auto *const data = (uint8_t *)&instr;
auto pc=start; auto pc=start;
auto* PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]); auto* PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
@ -368,6 +365,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]); auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
auto* icount = reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::ICOUNT]); auto* icount = reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::ICOUNT]);
auto* instret = reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::INSTRET]); auto* instret = reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::INSTRET]);
auto *const instruction = reinterpret_cast<code_word_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::INSTRUCTION]);
// we fetch at max 4 byte, alignment is 2
auto *const data = reinterpret_cast<uint8_t*>(instruction);
auto& instr = *instruction;
while(!this->core.should_stop() && while(!this->core.should_stop() &&
!(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){ !(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){
@ -2001,7 +2002,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
try { try {
{ {
uint8_t rs1_idx = rs1 + 8; uint32_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = *(X+rs1_idx) >> shamt; *(X+rs1_idx) = *(X+rs1_idx) >> shamt;
} }
} catch(...){} } catch(...){}
@ -2024,11 +2025,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
try { try {
if(shamt) { if(shamt) {
uint8_t rs1_idx = rs1 + 8; uint32_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt; *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt;
} }
else if(traits::XLEN == 128) { else if(traits::XLEN == 128) {
uint8_t rs1_idx = rs1 + 8; uint32_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64; *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64;
} }
} catch(...){} } catch(...){}
@ -2051,7 +2052,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
try { try {
{ {
uint8_t rs1_idx = rs1 + 8; uint32_t rs1_idx = rs1 + 8;
*(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm); *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm);
} }
} catch(...){} } catch(...){}
@ -2074,7 +2075,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
try { try {
{ {
uint8_t rd_idx = rd + 8; uint32_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8); *(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8);
} }
} catch(...){} } catch(...){}
@ -2097,7 +2098,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
try { try {
{ {
uint8_t rd_idx = rd + 8; uint32_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8); *(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8);
} }
} catch(...){} } catch(...){}
@ -2120,7 +2121,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
try { try {
{ {
uint8_t rd_idx = rd + 8; uint32_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8); *(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8);
} }
} catch(...){} } catch(...){}
@ -2143,7 +2144,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
try { try {
{ {
uint8_t rd_idx = rd + 8; uint32_t rd_idx = rd + 8;
*(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8); *(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8);
} }
} catch(...){} } catch(...){}