add code word access for ISS plugins
This commit is contained in:
parent
477c530847
commit
a92b84bef4
|
@ -1,6 +1,6 @@
|
|||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
|
||||
import "RV32I.core_desc"
|
||||
import "RVM.core_desc"
|
||||
import "RVC.core_desc"
|
||||
|
||||
Core TGC_C provides RV32I, Zicsr, Zifencei, RV32M, RV32IC {
|
||||
architectural_state {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
def getRegisterSizes(){
|
||||
def regs = registers.collect{it.size}
|
||||
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
|
||||
}
|
||||
%>
|
||||
|
|
|
@ -37,7 +37,7 @@ def nativeTypeSize(int size){
|
|||
}
|
||||
def getRegisterSizes(){
|
||||
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
|
||||
}
|
||||
def getRegisterOffsets(){
|
||||
|
@ -96,7 +96,8 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
|
|||
PENDING_TRAP,
|
||||
ICOUNT,
|
||||
CYCLE,
|
||||
INSTRET
|
||||
INSTRET,
|
||||
INSTRUCTION
|
||||
};
|
||||
|
||||
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;
|
||||
uint64_t icount = 0;
|
||||
uint64_t instret = 0;
|
||||
uint32_t instruction = 0;
|
||||
uint32_t last_branch;
|
||||
} reg;
|
||||
#pragma pack(pop)
|
||||
|
|
|
@ -277,9 +277,6 @@ typename arch::traits<ARCH>::opcode_e vm_impl<ARCH>::decode_inst_id(code_word_t
|
|||
|
||||
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){
|
||||
// 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 = 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* 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 *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() &&
|
||||
!(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){
|
||||
|
|
|
@ -235,9 +235,11 @@ protected:
|
|||
*/
|
||||
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; }
|
||||
|
||||
|
@ -249,8 +251,6 @@ protected:
|
|||
};
|
||||
|
||||
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 write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data);
|
||||
|
|
|
@ -53,7 +53,7 @@ template <> struct traits<tgc_c> {
|
|||
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"}};
|
||||
|
||||
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;
|
||||
|
||||
|
@ -63,7 +63,8 @@ template <> struct traits<tgc_c> {
|
|||
PENDING_TRAP,
|
||||
ICOUNT,
|
||||
CYCLE,
|
||||
INSTRET
|
||||
INSTRET,
|
||||
INSTRUCTION
|
||||
};
|
||||
|
||||
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>;
|
||||
|
||||
static constexpr std::array<const uint32_t, 41> 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}};
|
||||
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}};
|
||||
|
||||
static constexpr std::array<const uint32_t, 41> 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}};
|
||||
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,173}};
|
||||
|
||||
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;
|
||||
uint64_t icount = 0;
|
||||
uint64_t instret = 0;
|
||||
uint32_t instruction = 0;
|
||||
uint32_t last_branch;
|
||||
} reg;
|
||||
#pragma pack(pop)
|
||||
|
|
|
@ -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_aliases;
|
||||
constexpr std::array<const uint32_t, 41> 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_bit_widths;
|
||||
constexpr std::array<const uint32_t, 42> iss::arch::traits<iss::arch::tgc_c>::reg_byte_offsets;
|
||||
|
||||
tgc_c::tgc_c() {
|
||||
reg.icount = 0;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <iss/arch_if.h>
|
||||
#include <iss/plugin/pctrace.h>
|
||||
#include <util/logging.h>
|
||||
#include <util/ities.h>
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/istreamwrapper.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
|
||||
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;
|
||||
if (einfo.branch_taken)
|
||||
delay = entry.taken;
|
||||
|
|
|
@ -358,9 +358,6 @@ typename arch::traits<ARCH>::opcode_e vm_impl<ARCH>::decode_inst_id(code_word_t
|
|||
|
||||
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){
|
||||
// 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 = 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* 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 *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() &&
|
||||
!(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
|
||||
try {
|
||||
{
|
||||
uint8_t rs1_idx = rs1 + 8;
|
||||
uint32_t rs1_idx = rs1 + 8;
|
||||
*(X+rs1_idx) = *(X+rs1_idx) >> shamt;
|
||||
}
|
||||
} catch(...){}
|
||||
|
@ -2024,11 +2025,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||
// execute instruction
|
||||
try {
|
||||
if(shamt) {
|
||||
uint8_t rs1_idx = rs1 + 8;
|
||||
uint32_t rs1_idx = rs1 + 8;
|
||||
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt;
|
||||
}
|
||||
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;
|
||||
}
|
||||
} catch(...){}
|
||||
|
@ -2051,7 +2052,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||
// execute instruction
|
||||
try {
|
||||
{
|
||||
uint8_t rs1_idx = rs1 + 8;
|
||||
uint32_t rs1_idx = rs1 + 8;
|
||||
*(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm);
|
||||
}
|
||||
} catch(...){}
|
||||
|
@ -2074,7 +2075,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||
// execute instruction
|
||||
try {
|
||||
{
|
||||
uint8_t rd_idx = rd + 8;
|
||||
uint32_t rd_idx = rd + 8;
|
||||
*(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8);
|
||||
}
|
||||
} catch(...){}
|
||||
|
@ -2097,7 +2098,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||
// execute instruction
|
||||
try {
|
||||
{
|
||||
uint8_t rd_idx = rd + 8;
|
||||
uint32_t rd_idx = rd + 8;
|
||||
*(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8);
|
||||
}
|
||||
} catch(...){}
|
||||
|
@ -2120,7 +2121,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||
// execute instruction
|
||||
try {
|
||||
{
|
||||
uint8_t rd_idx = rd + 8;
|
||||
uint32_t rd_idx = rd + 8;
|
||||
*(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8);
|
||||
}
|
||||
} catch(...){}
|
||||
|
@ -2143,7 +2144,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||
// execute instruction
|
||||
try {
|
||||
{
|
||||
uint8_t rd_idx = rd + 8;
|
||||
uint32_t rd_idx = rd + 8;
|
||||
*(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8);
|
||||
}
|
||||
} catch(...){}
|
||||
|
|
Loading…
Reference in New Issue