Compare commits
13 Commits
msvc_compa
...
5866acf565
Author | SHA1 | Date | |
---|---|---|---|
5866acf565 | |||
6acf73a40f | |||
2f15d9676e | |||
d78fcc48e5 | |||
4186723d37 | |||
17ee7b138d | |||
aa84a27a5b | |||
438e598a4a | |||
174259155d | |||
ba9339a50d | |||
65b4db5eca | |||
0fd82f1f3c | |||
a3084456fd |
1
.gitignore
vendored
1
.gitignore
vendored
@ -31,3 +31,4 @@ language.settings.xml
|
||||
/*.out
|
||||
/dump.json
|
||||
/src-gen/
|
||||
/*.yaml
|
||||
|
@ -48,24 +48,16 @@ if(WITH_LLVM)
|
||||
endif()
|
||||
|
||||
# Define the library
|
||||
add_library(${PROJECT_NAME} ${LIB_SOURCES})
|
||||
add_library(${PROJECT_NAME} SHARED ${LIB_SOURCES})
|
||||
# list code gen dependencies
|
||||
if(TARGET ${CORE_NAME}_cpp)
|
||||
add_dependencies(${PROJECT_NAME} ${CORE_NAME}_cpp)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-shift-count-overflow)
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /wd4293)
|
||||
endif()
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-shift-count-overflow)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC incl)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp)
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-core)
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive)
|
||||
if(TARGET CONAN_PKG::elfio)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC CONAN_PKG::elfio)
|
||||
elseif(TARGET elfio::elfio)
|
||||
@ -106,15 +98,16 @@ if(WITH_LLVM)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs})
|
||||
endif()
|
||||
# Links the target exe against the libraries
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc)
|
||||
target_link_libraries(${PROJECT_NAME} dbt-rise-tgc)
|
||||
#target_link_libraries(${PROJECT_NAME} jsoncpp)
|
||||
if(TARGET Boost::program_options)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::program_options Boost::thread)
|
||||
target_link_libraries(${PROJECT_NAME} Boost::program_options Boost::thread)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY} ${BOOST_thread_LIBRARY})
|
||||
target_link_libraries(${PROJECT_NAME} ${BOOST_program_options_LIBRARY} ${BOOST_thread_LIBRARY})
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_DL_LIBS})
|
||||
target_link_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS})
|
||||
if (Tcmalloc_FOUND)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${Tcmalloc_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${Tcmalloc_LIBRARIES})
|
||||
endif(Tcmalloc_FOUND)
|
||||
|
||||
install(TARGETS tgc-sim
|
||||
|
Submodule gen_input/CoreDSL-Instruction-Set-Description updated: 8d9a0fb149...9e3119a806
14
gen_input/TGC_B.core_desc
Normal file
14
gen_input/TGC_B.core_desc
Normal file
@ -0,0 +1,14 @@
|
||||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
|
||||
|
||||
Core TGC_B provides RV32I {
|
||||
architectural_state {
|
||||
XLEN=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
unsigned MISA_VAL = 0b01000000000000000000000100000000;
|
||||
unsigned MARCHID_VAL = 0x80000002;
|
||||
}
|
||||
}
|
||||
|
13
gen_input/TGC_C.core_desc
Normal file
13
gen_input/TGC_C.core_desc
Normal file
@ -0,0 +1,13 @@
|
||||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
|
||||
|
||||
Core TGC_C provides RV32I, RV32M, RV32IC {
|
||||
architectural_state {
|
||||
XLEN=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
unsigned MISA_VAL = 0b01000000000000000001000100000100;
|
||||
unsigned MARCHID_VAL = 0x80000003;
|
||||
}
|
||||
}
|
13
gen_input/TGC_D.core_desc
Normal file
13
gen_input/TGC_D.core_desc
Normal file
@ -0,0 +1,13 @@
|
||||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
|
||||
|
||||
Core TGC_D provides RV32I, RV32M, RV32IC {
|
||||
architectural_state {
|
||||
XLEN=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
unsigned MISA_VAL = 0b01000000000000000001000100000100;
|
||||
unsigned MARCHID_VAL = 0x80000004;
|
||||
}
|
||||
}
|
73
gen_input/TGC_D_XRB_MAC.core_desc
Normal file
73
gen_input/TGC_D_XRB_MAC.core_desc
Normal file
@ -0,0 +1,73 @@
|
||||
import "CoreDSL-Instruction-Set-Description/RISCVBase.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
|
||||
|
||||
InstructionSet X_RB_MAC extends RISCVBase {
|
||||
architectural_state {
|
||||
register unsigned<64> ACC;
|
||||
}
|
||||
|
||||
instructions {
|
||||
RESET_ACC { // v-- funct7 v-- funct3
|
||||
encoding: 7'd0 :: 10'b0 :: 3'd0 :: 5'b0 :: 7'b0001011;
|
||||
behavior: ACC = 0;
|
||||
}
|
||||
|
||||
GET_ACC_LO {
|
||||
encoding: 7'd1 :: 10'b0 :: 3'd0 :: rd[4:0] :: 7'b0001011;
|
||||
behavior: if (rd != 0) X[rd] = ACC[31:0];
|
||||
}
|
||||
|
||||
GET_ACC_HI {
|
||||
encoding: 7'd2 :: 10'b0 :: 3'd0 :: rd[4:0] :: 7'b0001011;
|
||||
behavior: if (rd != 0) X[rd] = ACC[63:32];
|
||||
}
|
||||
|
||||
MACU_32 {
|
||||
encoding: 7'd0 :: rs2[4:0] :: rs1[4:0] :: 3'd1 :: 5'b0 :: 7'b0001011;
|
||||
behavior: {
|
||||
unsigned<64> mul = X[rs1] * X[rs2];
|
||||
unsigned<33> add = mul[31:0] + ACC[31:0];
|
||||
ACC = add[31:0];
|
||||
}
|
||||
}
|
||||
|
||||
MACS_32 {
|
||||
encoding: 7'd1 :: rs2[4:0] :: rs1[4:0] :: 3'd1 :: 5'b0 :: 7'b0001011;
|
||||
behavior: {
|
||||
signed<64> mul = ((signed) X[rs1]) * ((signed) X[rs2]);
|
||||
signed<33> add = ((signed) mul[31:0]) + ((signed) ACC[31:0]);
|
||||
ACC = add[31:0]; // bit range always yields unsigned type
|
||||
}
|
||||
}
|
||||
|
||||
MACU_64 {
|
||||
encoding: 7'd0 :: rs2[4:0] :: rs1[4:0] :: 3'd2 :: 5'b0 :: 7'b0001011;
|
||||
behavior: {
|
||||
unsigned<64> mul = X[rs1] * X[rs2];
|
||||
unsigned<65> add = mul + ACC;
|
||||
ACC = add[63:0];
|
||||
}
|
||||
}
|
||||
|
||||
MACS_64 {
|
||||
encoding: 7'd1 :: rs2[4:0] :: rs1[4:0] :: 3'd2 :: 5'b0 :: 7'b0001011;
|
||||
behavior: {
|
||||
signed<64> mul = ((signed) X[rs1]) * ((signed) X[rs2]);
|
||||
signed<65> add = mul + ((signed) ACC);
|
||||
ACC = add[63:0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Core TGC_D_XRB_MAC provides RV32I, RV32M, RV32IC, X_RB_MAC {
|
||||
architectural_state {
|
||||
XLEN=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
unsigned MISA_VAL = 0b01000000000000000001000100000100;
|
||||
unsigned MARCHID_VAL = 0x80000004;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
|
||||
|
||||
Core TGC_B provides RV32I {
|
||||
architectural_state {
|
||||
unsigned XLEN=32;
|
||||
unsigned PCLEN=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
unsigned MISA_VAL = 0b01000000000000000000000100000000;
|
||||
unsigned PGSIZE = 0x1000; //1 << 12;
|
||||
unsigned PGMASK = 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
|
||||
Core TGC_C provides RV32I, RV32M, RV32IC {
|
||||
architectural_state {
|
||||
unsigned XLEN=32;
|
||||
unsigned PCLEN=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
unsigned MISA_VAL = 0b01000000000000000001000100000100;
|
||||
unsigned PGSIZE = 0x1000; //1 << 12;
|
||||
unsigned PGMASK = 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
|
||||
Core TGC_D provides RV32I, RV32M, RV32IC {
|
||||
architectural_state {
|
||||
unsigned XLEN=32;
|
||||
unsigned PCLEN=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
unsigned MISA_VAL = 0b01000000000000000001000100000100;
|
||||
}
|
||||
}
|
16
gen_input/templates/CORENAME_instr.yaml.gtl
Normal file
16
gen_input/templates/CORENAME_instr.yaml.gtl
Normal file
@ -0,0 +1,16 @@
|
||||
<% def getInstructionGroups() {
|
||||
def instrGroups = [:]
|
||||
instructions.each {
|
||||
def groupName = it['instruction'].eContainer().name
|
||||
if(!instrGroups.containsKey(groupName)) {
|
||||
instrGroups[groupName]=[]
|
||||
}
|
||||
instrGroups[groupName]+=it;
|
||||
}
|
||||
instrGroups
|
||||
}%><%getInstructionGroups().each{name, instrList -> %>
|
||||
${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %>
|
||||
- ${it.instruction.name}
|
||||
encoding: ${it.encoding}
|
||||
mask: ${it.mask}<%}}%>
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
using addr_t = typename super::addr_t;
|
||||
using reg_t = typename traits::reg_t;
|
||||
using mem_type_e = typename traits::mem_type_e;
|
||||
|
||||
|
||||
vm_impl();
|
||||
|
||||
vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0);
|
||||
@ -324,6 +324,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
if (is_jump_to_self_enabled(cond) &&
|
||||
(insn == 0x0000006f || (insn&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||
auto f = decode_inst(insn);
|
||||
auto old_pc = pc.val;
|
||||
pc = (this->*f)(pc, insn);
|
||||
}
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p()
|
||||
// reset values
|
||||
csr[misa] = traits<BASE>::MISA_VAL;
|
||||
csr[mvendorid] = 0x669;
|
||||
csr[marchid] = 0x80000003;
|
||||
csr[marchid] = traits<BASE>::MARCHID_VAL;
|
||||
csr[mimpid] = 1;
|
||||
|
||||
uart_buf.str("");
|
||||
@ -362,8 +362,8 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p()
|
||||
csr_rd_cb[mie] = &this_class::read_ie;
|
||||
csr_wr_cb[mie] = &this_class::write_ie;
|
||||
csr_rd_cb[mhartid] = &this_class::read_hartid;
|
||||
csr_rd_cb[mcounteren] = &this_class::read_null;
|
||||
csr_wr_cb[mcounteren] = &this_class::write_null;
|
||||
// csr_rd_cb[mcounteren] = &this_class::read_null;
|
||||
// csr_wr_cb[mcounteren] = &this_class::write_null;
|
||||
csr_wr_cb[misa] = &this_class::write_null;
|
||||
csr_wr_cb[mvendorid] = &this_class::write_null;
|
||||
csr_wr_cb[marchid] = &this_class::write_null;
|
||||
@ -397,7 +397,7 @@ template <typename BASE> std::pair<uint64_t, bool> riscv_hart_m_p<BASE>::load_fi
|
||||
traits<BASE>::MEM, pseg->get_physical_address(),
|
||||
fsize, reinterpret_cast<const uint8_t *const>(seg_data));
|
||||
if (res != iss::Ok)
|
||||
LOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex
|
||||
LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex
|
||||
<< pseg->get_physical_address();
|
||||
}
|
||||
}
|
||||
@ -920,7 +920,16 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag
|
||||
if (trap_id == 0) { // exception
|
||||
// store ret addr in xepc register
|
||||
csr[mepc] = static_cast<reg_t>(addr) & get_pc_mask(); // store actual address instruction of exception
|
||||
csr[mtval] = cause==2?((instr & 0x3)==3?instr:instr&0xffff):fault_data;
|
||||
switch(cause){
|
||||
case 0:
|
||||
csr[mtval] = addr;
|
||||
break;
|
||||
case 2:
|
||||
csr[mtval] = (instr & 0x3)==3?instr:instr&0xffff;
|
||||
break;
|
||||
default:
|
||||
csr[mtval] = fault_data;
|
||||
}
|
||||
fault_data = 0;
|
||||
} else {
|
||||
csr[mepc] = this->reg.NEXT_PC & get_pc_mask(); // store next address if interrupt
|
||||
@ -948,11 +957,7 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag
|
||||
this->reg.PRIV = PRIV_M;
|
||||
this->reg.trap_state = 0;
|
||||
std::array<char, 32> buffer;
|
||||
#if defined(_MSC_VER)
|
||||
sprintf(buffer.data(), "0x%016llx", addr);
|
||||
#else
|
||||
sprintf(buffer.data(), "0x%016lx", addr);
|
||||
#endif
|
||||
if((flags&0xffffffff) != 0xffffffff)
|
||||
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
|
||||
<< (trap_id ? irq_str[cause] : trap_str[cause]) << "' (" << cause << ")"
|
||||
|
@ -145,7 +145,7 @@ public:
|
||||
|
||||
mstatus_t mstatus;
|
||||
|
||||
static const reg_t mstatus_reset_val = 0;
|
||||
static const reg_t mstatus_reset_val = 0x1800;
|
||||
|
||||
void write_mstatus(T val, unsigned priv_lvl) {
|
||||
auto mask = get_mask(priv_lvl);
|
||||
@ -398,7 +398,7 @@ private:
|
||||
iss::status read_ip(unsigned addr, reg_t &val);
|
||||
iss::status write_ip(unsigned addr, reg_t val);
|
||||
iss::status read_hartid(unsigned addr, reg_t &val);
|
||||
iss::status write_mepc(unsigned addr, reg_t val);
|
||||
iss::status write_epc(unsigned addr, reg_t val);
|
||||
iss::status read_satp(unsigned addr, reg_t &val);
|
||||
iss::status write_satp(unsigned addr, reg_t val);
|
||||
iss::status read_fcsr(unsigned addr, reg_t &val);
|
||||
@ -419,7 +419,7 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
|
||||
// reset values
|
||||
csr[misa] = traits<BASE>::MISA_VAL;
|
||||
csr[mvendorid] = 0x669;
|
||||
csr[marchid] = 0x80000003;
|
||||
csr[marchid] = traits<BASE>::MARCHID_VAL;
|
||||
csr[mimpid] = 1;
|
||||
|
||||
uart_buf.str("");
|
||||
@ -954,8 +954,8 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ip(unsigned
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_epc(unsigned addr, reg_t val) {
|
||||
csr[addr] = val & get_pc_mask();
|
||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_epc(unsigned addr, reg_t val) {
|
||||
csr[addr] = val & get_pc_mask();
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
|
||||
mstatus_t mstatus;
|
||||
|
||||
static const reg_t mstatus_reset_val = 0;
|
||||
static const reg_t mstatus_reset_val = 0x1800; // MPP set to 1
|
||||
|
||||
void write_mstatus(T val, unsigned priv_lvl) {
|
||||
auto mask = get_mask(priv_lvl);
|
||||
@ -349,7 +349,7 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p()
|
||||
// reset values
|
||||
csr[misa] = traits<BASE>::MISA_VAL;
|
||||
csr[mvendorid] = 0x669;
|
||||
csr[marchid] = 0x80000004;
|
||||
csr[marchid] = traits<BASE>::MARCHID_VAL;
|
||||
csr[mimpid] = 1;
|
||||
csr[mclicbase] = 0xc0000000; // TODO: should be taken from YAML file
|
||||
|
||||
@ -543,25 +543,27 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
|
||||
constexpr auto PMP_NA4 =0x2U;
|
||||
constexpr auto PMP_NAPOT =0x3U;
|
||||
reg_t base = 0;
|
||||
auto any_active = false;
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
|
||||
uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
|
||||
if (cfg & PMP_A) {
|
||||
any_active=true;
|
||||
auto pmp_a = (cfg & PMP_A) >> 3;
|
||||
bool is_tor = pmp_a == PMP_TOR;
|
||||
bool is_na4 = pmp_a == PMP_NA4;
|
||||
auto is_tor = pmp_a == PMP_TOR;
|
||||
auto is_na4 = pmp_a == PMP_NA4;
|
||||
|
||||
reg_t mask = (csr[pmpaddr0+i] << 1) | (!is_na4);
|
||||
mask = ~(mask & ~(mask + 1)) << PMP_SHIFT;
|
||||
|
||||
// Check each 4-byte sector of the access
|
||||
bool any_match = false;
|
||||
bool all_match = true;
|
||||
auto any_match = false;
|
||||
auto all_match = true;
|
||||
for (reg_t offset = 0; offset < len; offset += 1 << PMP_SHIFT) {
|
||||
reg_t cur_addr = addr + offset;
|
||||
bool napot_match = ((cur_addr ^ tor) & mask) == 0;
|
||||
bool tor_match = base <= cur_addr && cur_addr < tor;
|
||||
bool match = is_tor ? tor_match : napot_match;
|
||||
auto napot_match = ((cur_addr ^ tor) & mask) == 0;
|
||||
auto tor_match = base <= cur_addr && cur_addr < tor;
|
||||
auto match = is_tor ? tor_match : napot_match;
|
||||
any_match |= match;
|
||||
all_match &= match;
|
||||
}
|
||||
@ -577,7 +579,7 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
|
||||
}
|
||||
base = tor;
|
||||
}
|
||||
return this->reg.PRIV == PRIV_M;
|
||||
return !any_active || this->reg.PRIV == PRIV_M;
|
||||
}
|
||||
|
||||
|
||||
@ -926,8 +928,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
|
||||
|
||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ie(unsigned addr, reg_t val) {
|
||||
auto mask = get_irq_wrmask((addr >> 8) & 0x3);
|
||||
if(this->reg.PRIV==0)
|
||||
mask&= ~(0xff<<4); // STIE and UTIE are read only in user and supervisor mode
|
||||
csr[mie] = (csr[mie] & ~mask) | (val & mask);
|
||||
check_interrupt();
|
||||
return iss::Ok;
|
||||
@ -1256,27 +1256,33 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::
|
||||
template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::leave_trap(uint64_t flags) {
|
||||
auto cur_priv = this->reg.PRIV;
|
||||
auto inst_priv = (flags & 0x3)? 3:0;
|
||||
auto status = state.mstatus;
|
||||
// pop the relevant lower-privilege interrupt enable and privilege mode stack
|
||||
// clear respective yIE
|
||||
switch (inst_priv) {
|
||||
case PRIV_M:
|
||||
this->reg.PRIV = state.mstatus.MPP;
|
||||
state.mstatus.MPP = 0; // clear mpp to U mode
|
||||
state.mstatus.MIE = state.mstatus.MPIE;
|
||||
state.mstatus.MPIE = 1;
|
||||
break;
|
||||
case PRIV_U:
|
||||
this->reg.PRIV = 0;
|
||||
state.mstatus.UIE = state.mstatus.UPIE;
|
||||
state.mstatus.UPIE = 1;
|
||||
break;
|
||||
if(inst_priv>cur_priv){
|
||||
auto trap_val = 0x80ULL << 24 | (2 << 16); // illegal instruction
|
||||
this->reg.trap_state = trap_val;
|
||||
this->reg.NEXT_PC = std::numeric_limits<uint32_t>::max();
|
||||
} else {
|
||||
auto status = state.mstatus;
|
||||
// pop the relevant lower-privilege interrupt enable and privilege mode stack
|
||||
// clear respective yIE
|
||||
switch (inst_priv) {
|
||||
case PRIV_M:
|
||||
this->reg.PRIV = state.mstatus.MPP;
|
||||
state.mstatus.MPP = 0; // clear mpp to U mode
|
||||
state.mstatus.MIE = state.mstatus.MPIE;
|
||||
state.mstatus.MPIE = 1;
|
||||
break;
|
||||
case PRIV_U:
|
||||
this->reg.PRIV = 0;
|
||||
state.mstatus.UIE = state.mstatus.UPIE;
|
||||
state.mstatus.UPIE = 1;
|
||||
break;
|
||||
}
|
||||
// sets the pc to the value stored in the x epc register.
|
||||
this->reg.NEXT_PC = csr[uepc | inst_priv << 8];
|
||||
CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to "
|
||||
<< lvl[this->reg.PRIV];
|
||||
check_interrupt();
|
||||
}
|
||||
// sets the pc to the value stored in the x epc register.
|
||||
this->reg.NEXT_PC = csr[uepc | inst_priv << 8];
|
||||
CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to "
|
||||
<< lvl[this->reg.PRIV];
|
||||
check_interrupt();
|
||||
return this->reg.NEXT_PC;
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,9 @@ template <> struct traits<tgc_c> {
|
||||
{"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}};
|
||||
|
||||
static constexpr std::array<const char*, 35> reg_aliases{
|
||||
{"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}};
|
||||
{"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"}};
|
||||
|
||||
enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b01000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0b111111111111, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64};
|
||||
enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, 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;
|
||||
|
||||
|
@ -49,9 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*----------------------------------------------------------------------------*/
|
||||
#ifdef __GNUC__
|
||||
#define SOFTFLOAT_BUILTIN_CLZ 1
|
||||
#define SOFTFLOAT_INTRINSIC_INT128 1
|
||||
#endif
|
||||
#include "opts-GCC.h"
|
||||
|
||||
|
17
src/main.cpp
17
src/main.cpp
@ -49,6 +49,11 @@ using tgc_b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_b>;
|
||||
#include "iss/arch/tgc_d.h"
|
||||
using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
|
||||
#endif
|
||||
#ifdef CORE_TGC_D_XRB_MAC
|
||||
#include "iss/arch/riscv_hart_mu_p.h"
|
||||
#include "iss/arch/tgc_d_xrb_mac.h"
|
||||
using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
|
||||
#endif
|
||||
#ifdef WITH_LLVM
|
||||
#include <iss/llvm/jit_helper.h>
|
||||
#endif
|
||||
@ -138,9 +143,15 @@ int main(int argc, char *argv[]) {
|
||||
std::tie(cpu, vm) =
|
||||
iss::create_cpu<tgc_d_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
|
||||
} else
|
||||
#endif
|
||||
#ifdef CORE_TGC_D_XRB_MAC
|
||||
if (isa_opt == "tgc_d_xrb_mac") {
|
||||
std::tie(cpu, vm) =
|
||||
iss::create_cpu<tgc_d_xrb_mac_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
LOG(ERR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
|
||||
LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
|
||||
return 127;
|
||||
}
|
||||
if (clim.count("plugin")) {
|
||||
@ -161,7 +172,7 @@ int main(int argc, char *argv[]) {
|
||||
vm->register_plugin(*ce_plugin);
|
||||
plugin_list.push_back(ce_plugin);
|
||||
} else {
|
||||
LOG(ERR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl;
|
||||
LOG(ERROR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl;
|
||||
return 127;
|
||||
}
|
||||
}
|
||||
@ -196,7 +207,7 @@ int main(int argc, char *argv[]) {
|
||||
auto cycles = clim["instructions"].as<uint64_t>();
|
||||
res = vm->start(cycles, dump);
|
||||
} catch (std::exception &e) {
|
||||
LOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit"
|
||||
LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit"
|
||||
<< std::endl;
|
||||
res = 2;
|
||||
}
|
||||
|
@ -47,10 +47,10 @@ iss::plugin::cycle_estimate::cycle_estimate(std::string config_file_name)
|
||||
try {
|
||||
is >> root;
|
||||
} catch (Json::RuntimeError &e) {
|
||||
LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
|
||||
LOG(ERROR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
|
||||
}
|
||||
} else {
|
||||
LOG(ERR) << "Could not open input file " << config_file_name;
|
||||
LOG(ERROR) << "Could not open input file " << config_file_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -77,7 +77,7 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<std::endl;
|
||||
LOG(ERROR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<std::endl;
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -87,8 +87,6 @@ void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info co
|
||||
assert(arch_instr && "No instrumentation interface available but callback executed");
|
||||
auto entry = delays[instr_info.instr_id];
|
||||
bool taken = (arch_instr->get_next_pc()-arch_instr->get_pc()) != (entry.size/8);
|
||||
if (taken && entry.taken > 1)
|
||||
arch_instr->set_curr_instr_cycles(entry.taken);
|
||||
else if (entry.not_taken > 1)
|
||||
arch_instr->set_curr_instr_cycles(entry.not_taken);
|
||||
uint32_t delay = taken ? entry.taken : entry.not_taken;
|
||||
if(delay>1) arch_instr->set_curr_instr_cycles(delay);
|
||||
}
|
||||
|
@ -46,10 +46,10 @@ iss::plugin::instruction_count::instruction_count(std::string config_file_name)
|
||||
try {
|
||||
is >> root;
|
||||
} catch (Json::RuntimeError &e) {
|
||||
LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
|
||||
LOG(ERROR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
|
||||
}
|
||||
} else {
|
||||
LOG(ERR) << "Could not open input file " << config_file_name;
|
||||
LOG(ERROR) << "Could not open input file " << config_file_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,7 @@ bool iss::plugin::instruction_count::registration(const char* const version, vm_
|
||||
}
|
||||
rep_counts.resize(delays.size());
|
||||
} else {
|
||||
LOG(ERR)<<"plugin instruction_count: could not find an entry for "<<core_name<<" in JSON file"<<std::endl;
|
||||
LOG(ERROR)<<"plugin instruction_count: could not find an entry for "<<core_name<<" in JSON file"<<std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -30,13 +30,6 @@
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
// clang-format off
|
||||
#include "iss/debugger/gdb_session.h"
|
||||
#include "iss/debugger/encoderdecoder.h"
|
||||
#include "iss/debugger/server.h"
|
||||
#include "iss/debugger/target_adapter_if.h"
|
||||
#include "iss/iss.h"
|
||||
#include "iss/vm_types.h"
|
||||
#include "sysc/core_complex.h"
|
||||
#ifdef CORE_TGC_B
|
||||
#include "iss/arch/riscv_hart_m_p.h"
|
||||
@ -51,11 +44,21 @@ using tgc_c_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c>;
|
||||
#include "iss/arch/tgc_d.h"
|
||||
using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, iss::arch::FEAT_PMP>;
|
||||
#endif
|
||||
#ifdef CORE_TGC_D_XRB_MAC
|
||||
#include "iss/arch/riscv_hart_mu_p.h"
|
||||
#include "iss/arch/tgc_d_xrb_mac.h"
|
||||
using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, iss::arch::FEAT_PMP>;
|
||||
#endif
|
||||
#include "iss/debugger/encoderdecoder.h"
|
||||
#include "iss/debugger/gdb_session.h"
|
||||
#include "iss/debugger/server.h"
|
||||
#include "iss/debugger/target_adapter_if.h"
|
||||
#include "iss/iss.h"
|
||||
#include "iss/vm_types.h"
|
||||
#include "scc/report.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <array>
|
||||
// clang-format on
|
||||
|
||||
#define STR(X) #X
|
||||
#define CREATE_CORE(CN) \
|
||||
@ -74,12 +77,6 @@ using namespace scv_tr;
|
||||
#define GET_PROP_VALUE(P) P.getValue()
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// not #if defined(_WIN32) || defined(_WIN64) because we have strncasecmp in mingw
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
namespace sysc {
|
||||
namespace tgfs {
|
||||
using namespace std;
|
||||
@ -293,9 +290,12 @@ public:
|
||||
#endif
|
||||
#ifdef CORE_TGC_D
|
||||
CREATE_CORE(tgc_d)
|
||||
#endif
|
||||
#ifdef CORE_TGC_D_XRB_MACD
|
||||
CREATE_CORE(tgc_d_xrb_mac)
|
||||
#endif
|
||||
{
|
||||
LOG(ERR) << "Illegal argument value for core type: " << type << std::endl;
|
||||
LOG(ERROR) << "Illegal argument value for core type: " << type << std::endl;
|
||||
}
|
||||
auto *srv = debugger::server<debugger::gdb_session>::get();
|
||||
if (srv) tgt_adapter = srv->get_target();
|
||||
|
@ -30,21 +30,23 @@
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
// clang-format off
|
||||
#include "../fp_functions.h"
|
||||
#include <iss/arch/tgc_c.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/debugger/gdb_session.h>
|
||||
#include <iss/debugger/server.h>
|
||||
#include <iss/iss.h>
|
||||
#include <iss/arch/tgc_c.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/interp/vm_base.h>
|
||||
#include "../fp_functions.h"
|
||||
#include <util/logging.h>
|
||||
#include <sstream>
|
||||
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
#define FMT_HEADER_ONLY
|
||||
#endif
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <array>
|
||||
#include <iss/debugger/riscv_target_adapter.h>
|
||||
// clang-format on
|
||||
|
||||
namespace iss {
|
||||
namespace interp {
|
||||
@ -62,7 +64,7 @@ public:
|
||||
using addr_t = typename super::addr_t;
|
||||
using reg_t = typename traits::reg_t;
|
||||
using mem_type_e = typename traits::mem_type_e;
|
||||
|
||||
|
||||
vm_impl();
|
||||
|
||||
vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0);
|
||||
@ -461,8 +463,13 @@ private:
|
||||
// execute instruction
|
||||
try {
|
||||
{
|
||||
if(rd != 0) *(X+rd) = *PC + 4;
|
||||
pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm);
|
||||
if(imm % traits::INSTR_ALIGNMENT) {
|
||||
raise(0, 0);
|
||||
}
|
||||
else {
|
||||
if(rd != 0) *(X+rd) = *PC + 4;
|
||||
pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm);
|
||||
}
|
||||
}
|
||||
} catch(...){}
|
||||
// post execution stuff
|
||||
@ -505,9 +512,14 @@ private:
|
||||
// execute instruction
|
||||
try {
|
||||
{
|
||||
int32_t new_pc = *(X+rs1) + (int16_t)sext<12>(imm);
|
||||
if(rd != 0) *(X+rd) = *PC + 4;
|
||||
pc_assign(*NEXT_PC) = new_pc & ~ 0x1;
|
||||
int32_t new_pc = (*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 1;
|
||||
if(new_pc % traits::INSTR_ALIGNMENT) {
|
||||
raise(0, 0);
|
||||
}
|
||||
else {
|
||||
if(rd != 0) *(X+rd) = *PC + 4;
|
||||
pc_assign(*NEXT_PC) = new_pc & ~ 0x1;
|
||||
}
|
||||
}
|
||||
} catch(...){}
|
||||
// post execution stuff
|
||||
@ -549,7 +561,12 @@ private:
|
||||
*NEXT_PC = *PC + 4;
|
||||
// execute instruction
|
||||
try {
|
||||
if(*(X+rs1) == *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
{
|
||||
if(*(X+rs1) == *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
|
||||
raise(0, 0);
|
||||
}
|
||||
else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
}
|
||||
} catch(...){}
|
||||
// post execution stuff
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4);
|
||||
@ -590,7 +607,12 @@ private:
|
||||
*NEXT_PC = *PC + 4;
|
||||
// execute instruction
|
||||
try {
|
||||
if(*(X+rs1) != *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
{
|
||||
if(*(X+rs1) != *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
|
||||
raise(0, 0);
|
||||
}
|
||||
else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
}
|
||||
} catch(...){}
|
||||
// post execution stuff
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5);
|
||||
@ -631,7 +653,12 @@ private:
|
||||
*NEXT_PC = *PC + 4;
|
||||
// execute instruction
|
||||
try {
|
||||
if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
{
|
||||
if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
|
||||
raise(0, 0);
|
||||
}
|
||||
else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
}
|
||||
} catch(...){}
|
||||
// post execution stuff
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6);
|
||||
@ -672,7 +699,12 @@ private:
|
||||
*NEXT_PC = *PC + 4;
|
||||
// execute instruction
|
||||
try {
|
||||
if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
{
|
||||
if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
|
||||
raise(0, 0);
|
||||
}
|
||||
else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
}
|
||||
} catch(...){}
|
||||
// post execution stuff
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7);
|
||||
@ -713,7 +745,12 @@ private:
|
||||
*NEXT_PC = *PC + 4;
|
||||
// execute instruction
|
||||
try {
|
||||
if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
{
|
||||
if(*(X+rs1) < *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
|
||||
raise(0, 0);
|
||||
}
|
||||
else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
}
|
||||
} catch(...){}
|
||||
// post execution stuff
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8);
|
||||
@ -754,7 +791,12 @@ private:
|
||||
*NEXT_PC = *PC + 4;
|
||||
// execute instruction
|
||||
try {
|
||||
if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
{
|
||||
if(*(X+rs1) >= *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
|
||||
raise(0, 0);
|
||||
}
|
||||
else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
|
||||
}
|
||||
} catch(...){}
|
||||
// post execution stuff
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9);
|
||||
@ -4136,9 +4178,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||
this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
|
||||
pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
|
||||
} else {
|
||||
if (is_jump_to_self_enabled(cond) && (insn == 0x0000006f || (insn&0xffff)==0xa001))
|
||||
throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||
if (is_jump_to_self_enabled(cond) &&
|
||||
(insn == 0x0000006f || (insn&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||
auto f = decode_inst(insn);
|
||||
auto old_pc = pc.val;
|
||||
pc = (this->*f)(pc, insn);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user