From a3084456fdf816db6234980024384e88f19b0466 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 4 Sep 2021 12:46:56 +0200 Subject: [PATCH 01/37] rework core definitions --- gen_input/TGC_B.core_desc | 16 +++++++ gen_input/TGC_C.core_desc | 15 +++++++ gen_input/TGC_D.core_desc | 13 ++++++ gen_input/TGC_D_XRB_MAC.core_desc | 73 +++++++++++++++++++++++++++++++ gen_input/TGFS.core_desc | 37 ---------------- 5 files changed, 117 insertions(+), 37 deletions(-) create mode 100644 gen_input/TGC_B.core_desc create mode 100644 gen_input/TGC_C.core_desc create mode 100644 gen_input/TGC_D.core_desc create mode 100644 gen_input/TGC_D_XRB_MAC.core_desc delete mode 100644 gen_input/TGFS.core_desc diff --git a/gen_input/TGC_B.core_desc b/gen_input/TGC_B.core_desc new file mode 100644 index 0000000..d7bd320 --- /dev/null +++ b/gen_input/TGC_B.core_desc @@ -0,0 +1,16 @@ +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 + } +} + diff --git a/gen_input/TGC_C.core_desc b/gen_input/TGC_C.core_desc new file mode 100644 index 0000000..9d3b202 --- /dev/null +++ b/gen_input/TGC_C.core_desc @@ -0,0 +1,15 @@ +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 { + 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 + } +} diff --git a/gen_input/TGC_D.core_desc b/gen_input/TGC_D.core_desc new file mode 100644 index 0000000..cf346b2 --- /dev/null +++ b/gen_input/TGC_D.core_desc @@ -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 { + unsigned XLEN=32; + unsigned PCLEN=32; + // definitions for the architecture wrapper + // XL ZYXWVUTSRQPONMLKJIHGFEDCBA + unsigned MISA_VAL = 0b01000000000000000001000100000100; + } +} diff --git a/gen_input/TGC_D_XRB_MAC.core_desc b/gen_input/TGC_D_XRB_MAC.core_desc new file mode 100644 index 0000000..dd4cfbe --- /dev/null +++ b/gen_input/TGC_D_XRB_MAC.core_desc @@ -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 { + unsigned XLEN=32; + unsigned PCLEN=32; + // definitions for the architecture wrapper + // XL ZYXWVUTSRQPONMLKJIHGFEDCBA + unsigned MISA_VAL = 0b01000000000000000001000100000100; + } +} diff --git a/gen_input/TGFS.core_desc b/gen_input/TGFS.core_desc deleted file mode 100644 index ba2a63f..0000000 --- a/gen_input/TGFS.core_desc +++ /dev/null @@ -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; - } -} From 0fd82f1f3c0371fa3b629f96dab598991168eed1 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 4 Sep 2021 13:04:34 +0200 Subject: [PATCH 02/37] add tgc_d_xrb_mac to SC and C++ ISS --- src/main.cpp | 11 +++++++++++ src/sysc/core_complex.cpp | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index ac139d1..7a6711b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -49,6 +49,11 @@ using tgc_b_plat_type = iss::arch::riscv_hart_m_p; #include "iss/arch/tgc_d.h" using tgc_d_plat_type = iss::arch::riscv_hart_mu_p; #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; +#endif #ifdef WITH_LLVM #include #endif @@ -138,6 +143,12 @@ int main(int argc, char *argv[]) { std::tie(cpu, vm) = iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); } else +#endif +#ifdef CORE_TGC_D_XRB_MAC + if (isa_opt == "tgc_d_xrb_mac") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else #endif { LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as() << std::endl; diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 0e841ce..6b5e391 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -44,6 +44,11 @@ using tgc_c_plat_type = iss::arch::riscv_hart_m_p; #include "iss/arch/tgc_d.h" using tgc_d_plat_type = iss::arch::riscv_hart_mu_p; #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; +#endif #include "iss/debugger/encoderdecoder.h" #include "iss/debugger/gdb_session.h" #include "iss/debugger/server.h" @@ -285,6 +290,9 @@ 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(ERROR) << "Illegal argument value for core type: " << type << std::endl; From 65b4db5eca4b24da784b114403c0855ef1d44c03 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 18 Sep 2021 11:40:00 +0200 Subject: [PATCH 03/37] remove mcounteren in M-mode only platform --- incl/iss/arch/riscv_hart_m_p.h | 4 ++-- src/vm/interp/vm_tgc_c.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 0104e2c..87066f3 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -362,8 +362,8 @@ riscv_hart_m_p::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; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index e142646..01985ba 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -4138,8 +4138,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co this->do_sync(POST_SYNC, std::numeric_limits::max()); pc.val = super::core.enter_trap(std::numeric_limits::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); pc = (this->*f)(pc, insn); } From ba9339a50d5ac5591fb96ac233d264a25e38a323 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 21 Sep 2021 16:52:40 +0200 Subject: [PATCH 04/37] fix MPP reset value, PMP inactive in U-mode handling and MRET in U-mode --- incl/iss/arch/riscv_hart_msu_vp.h | 8 ++-- incl/iss/arch/riscv_hart_mu_p.h | 68 +++++++++++++++++-------------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index ff1ed78..2dbfef2 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -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); @@ -954,8 +954,8 @@ template iss::status riscv_hart_msu_vp::write_ip(unsigned return iss::Ok; } -template iss::status riscv_hart_m_p::write_epc(unsigned addr, reg_t val) { - csr[addr] = val & get_pc_mask(); +template iss::status riscv_hart_msu_vp::write_epc(unsigned addr, reg_t val) { + csr[addr] = val & get_pc_mask(); return iss::Ok; } diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 8d01c3f..b931fb2 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -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); @@ -543,25 +543,27 @@ template bool riscv_hart_mu_p::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 bool riscv_hart_mu_p::pmp_ } base = tor; } - return this->reg.PRIV == PRIV_M; + return !any_active || this->reg.PRIV == PRIV_M; } @@ -926,8 +928,6 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::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 uint64_t riscv_hart_mu_p:: template uint64_t riscv_hart_mu_p::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::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; } From 174259155df927075f551445994d8cc231d182e5 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 23 Sep 2021 21:09:36 +0200 Subject: [PATCH 05/37] add support for non-compressed ISA --- gen_input/templates/interp/CORENAME.cpp.gtl | 6 +- incl/iss/arch/riscv_hart_m_p.h | 11 ++- src/vm/interp/vm_tgc_c.cpp | 93 ++++++++++++++++++++- 3 files changed, 107 insertions(+), 3 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 65d3b5b..f2b86ae 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -64,7 +64,9 @@ public: using addr_t = typename super::addr_t; using reg_t = typename traits::reg_t; using mem_type_e = typename traits::mem_type_e; - + + const bool has_compressed = traits::MISA_VAL & 0b100; + vm_impl(); vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); @@ -210,6 +212,7 @@ private: <%instr.behavior.eachLine{%>${it} <%}%>} catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx}); // trap check if(*trap_state!=0){ @@ -324,6 +327,7 @@ typename vm_base::virt_addr_t vm_impl::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); } } diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 87066f3..9d93bd2 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -920,7 +920,16 @@ template uint64_t riscv_hart_m_p::enter_trap(uint64_t flag if (trap_id == 0) { // exception // store ret addr in xepc register csr[mepc] = static_cast(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] = instr; + 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 diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 01985ba..f2686de 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -64,7 +64,9 @@ public: using addr_t = typename super::addr_t; using reg_t = typename traits::reg_t; using mem_type_e = typename traits::mem_type_e; - + + const bool has_compressed = traits::MISA_VAL & 0b100; + vm_impl(); vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); @@ -385,6 +387,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)imm; } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 0); // trap check if(*trap_state!=0){ @@ -425,6 +428,7 @@ private: if(rd != 0) *(X+rd) = *PC + (int32_t)imm; } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 1); // trap check if(*trap_state!=0){ @@ -468,6 +472,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); // trap check if(*trap_state!=0){ @@ -513,6 +518,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3); // trap check if(*trap_state!=0){ @@ -554,6 +560,7 @@ private: if(*(X+rs1) == *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); // trap check if(*trap_state!=0){ @@ -595,6 +602,7 @@ private: if(*(X+rs1) != *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); // trap check if(*trap_state!=0){ @@ -636,6 +644,7 @@ private: if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); // trap check if(*trap_state!=0){ @@ -677,6 +686,7 @@ private: if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); // trap check if(*trap_state!=0){ @@ -718,6 +728,7 @@ private: if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); // trap check if(*trap_state!=0){ @@ -759,6 +770,7 @@ private: if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); // trap check if(*trap_state!=0){ @@ -803,6 +815,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10); // trap check if(*trap_state!=0){ @@ -848,6 +861,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11); // trap check if(*trap_state!=0){ @@ -893,6 +907,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12); // trap check if(*trap_state!=0){ @@ -937,6 +952,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13); // trap check if(*trap_state!=0){ @@ -982,6 +998,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14); // trap check if(*trap_state!=0){ @@ -1023,6 +1040,7 @@ private: writeSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2)); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); // trap check if(*trap_state!=0){ @@ -1067,6 +1085,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16); // trap check if(*trap_state!=0){ @@ -1111,6 +1130,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17); // trap check if(*trap_state!=0){ @@ -1152,6 +1172,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); // trap check if(*trap_state!=0){ @@ -1193,6 +1214,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); // trap check if(*trap_state!=0){ @@ -1234,6 +1256,7 @@ private: if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 20); // trap check if(*trap_state!=0){ @@ -1275,6 +1298,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); // trap check if(*trap_state!=0){ @@ -1316,6 +1340,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); // trap check if(*trap_state!=0){ @@ -1357,6 +1382,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); // trap check if(*trap_state!=0){ @@ -1403,6 +1429,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24); // trap check if(*trap_state!=0){ @@ -1449,6 +1476,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25); // trap check if(*trap_state!=0){ @@ -1495,6 +1523,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26); // trap check if(*trap_state!=0){ @@ -1536,6 +1565,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 27); // trap check if(*trap_state!=0){ @@ -1577,6 +1607,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 28); // trap check if(*trap_state!=0){ @@ -1618,6 +1649,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 29); // trap check if(*trap_state!=0){ @@ -1659,6 +1691,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 30); // trap check if(*trap_state!=0){ @@ -1700,6 +1733,7 @@ private: if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 31); // trap check if(*trap_state!=0){ @@ -1741,6 +1775,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 32); // trap check if(*trap_state!=0){ @@ -1782,6 +1817,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 33); // trap check if(*trap_state!=0){ @@ -1823,6 +1859,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 34); // trap check if(*trap_state!=0){ @@ -1864,6 +1901,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 35); // trap check if(*trap_state!=0){ @@ -1905,6 +1943,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 36); // trap check if(*trap_state!=0){ @@ -1947,6 +1986,7 @@ private: writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 37); // trap check if(*trap_state!=0){ @@ -1981,6 +2021,7 @@ private: raise(0, 11); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 38); // trap check if(*trap_state!=0){ @@ -2015,6 +2056,7 @@ private: raise(0, 3); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 39); // trap check if(*trap_state!=0){ @@ -2049,6 +2091,7 @@ private: leave(0); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 40); // trap check if(*trap_state!=0){ @@ -2083,6 +2126,7 @@ private: leave(1); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 41); // trap check if(*trap_state!=0){ @@ -2117,6 +2161,7 @@ private: leave(3); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 42); // trap check if(*trap_state!=0){ @@ -2151,6 +2196,7 @@ private: wait(1); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 43); // trap check if(*trap_state!=0){ @@ -2202,6 +2248,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); // trap check if(*trap_state!=0){ @@ -2248,6 +2295,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); // trap check if(*trap_state!=0){ @@ -2294,6 +2342,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); // trap check if(*trap_state!=0){ @@ -2339,6 +2388,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); // trap check if(*trap_state!=0){ @@ -2384,6 +2434,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); // trap check if(*trap_state!=0){ @@ -2429,6 +2480,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); // trap check if(*trap_state!=0){ @@ -2475,6 +2527,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); // trap check if(*trap_state!=0){ @@ -2521,6 +2574,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); // trap check if(*trap_state!=0){ @@ -2567,6 +2621,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); // trap check if(*trap_state!=0){ @@ -2613,6 +2668,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); // trap check if(*trap_state!=0){ @@ -2663,6 +2719,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); // trap check if(*trap_state!=0){ @@ -2709,6 +2766,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); // trap check if(*trap_state!=0){ @@ -2759,6 +2817,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); // trap check if(*trap_state!=0){ @@ -2805,6 +2864,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); // trap check if(*trap_state!=0){ @@ -2846,6 +2906,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); // trap check if(*trap_state!=0){ @@ -2890,6 +2951,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); // trap check if(*trap_state!=0){ @@ -2934,6 +2996,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); // trap check if(*trap_state!=0){ @@ -2974,6 +3037,7 @@ private: *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); // trap check if(*trap_state!=0){ @@ -3010,6 +3074,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); // trap check if(*trap_state!=0){ @@ -3052,6 +3117,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); // trap check if(*trap_state!=0){ @@ -3094,6 +3160,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); // trap check if(*trap_state!=0){ @@ -3137,6 +3204,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); // trap check if(*trap_state!=0){ @@ -3177,6 +3245,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); // trap check if(*trap_state!=0){ @@ -3212,6 +3281,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); // trap check if(*trap_state!=0){ @@ -3255,6 +3325,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); // trap check if(*trap_state!=0){ @@ -3302,6 +3373,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); // trap check if(*trap_state!=0){ @@ -3345,6 +3417,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); // trap check if(*trap_state!=0){ @@ -3388,6 +3461,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); // trap check if(*trap_state!=0){ @@ -3431,6 +3505,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); // trap check if(*trap_state!=0){ @@ -3474,6 +3549,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); // trap check if(*trap_state!=0){ @@ -3517,6 +3593,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); // trap check if(*trap_state!=0){ @@ -3555,6 +3632,7 @@ private: pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); // trap check if(*trap_state!=0){ @@ -3595,6 +3673,7 @@ private: if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); // trap check if(*trap_state!=0){ @@ -3635,6 +3714,7 @@ private: if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); // trap check if(*trap_state!=0){ @@ -3675,6 +3755,7 @@ private: if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); // trap check if(*trap_state!=0){ @@ -3719,6 +3800,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); // trap check if(*trap_state!=0){ @@ -3759,6 +3841,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); // trap check if(*trap_state!=0){ @@ -3799,6 +3882,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); // trap check if(*trap_state!=0){ @@ -3833,6 +3917,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); // trap check if(*trap_state!=0){ @@ -3873,6 +3958,7 @@ private: if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); // trap check if(*trap_state!=0){ @@ -3916,6 +4002,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); // trap check if(*trap_state!=0){ @@ -3950,6 +4037,7 @@ private: raise(0, 3); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); // trap check if(*trap_state!=0){ @@ -3993,6 +4081,7 @@ private: } } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); // trap check if(*trap_state!=0){ @@ -4027,6 +4116,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff + if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); // trap check if(*trap_state!=0){ @@ -4141,6 +4231,7 @@ typename vm_base::virt_addr_t vm_impl::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); } } From 438e598a4aaf287298596e3ceb6609ee36818fee Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 29 Sep 2021 00:03:11 +0200 Subject: [PATCH 06/37] remove clutter from core descriptions, added instr alignment setting --- gen_input/CoreDSL-Instruction-Set-Description | 2 +- gen_input/TGC_B.core_desc | 5 +- gen_input/TGC_C.core_desc | 5 +- gen_input/TGC_D.core_desc | 3 +- gen_input/TGC_D_XRB_MAC.core_desc | 3 +- incl/iss/arch/tgc_c.h | 4 +- src/vm/interp/vm_tgc_c.cpp | 60 +++++++++++++++---- 7 files changed, 57 insertions(+), 25 deletions(-) diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description index 8d9a0fb..89dabd0 160000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ b/gen_input/CoreDSL-Instruction-Set-Description @@ -1 +1 @@ -Subproject commit 8d9a0fb1493b762014c330c71ac8cef96753d302 +Subproject commit 89dabd00e3380d41070b126f8d6d1548056619c1 diff --git a/gen_input/TGC_B.core_desc b/gen_input/TGC_B.core_desc index d7bd320..12263b9 100644 --- a/gen_input/TGC_B.core_desc +++ b/gen_input/TGC_B.core_desc @@ -4,13 +4,10 @@ import "CoreDSL-Instruction-Set-Description/RVC.core_desc" Core TGC_B provides RV32I { architectural_state { - unsigned XLEN=32; - unsigned PCLEN=32; + XLEN=32; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA unsigned MISA_VAL = 0b01000000000000000000000100000000; - unsigned PGSIZE = 0x1000; //1 << 12; - unsigned PGMASK = 0xfff; //PGSIZE-1 } } diff --git a/gen_input/TGC_C.core_desc b/gen_input/TGC_C.core_desc index 9d3b202..93237ef 100644 --- a/gen_input/TGC_C.core_desc +++ b/gen_input/TGC_C.core_desc @@ -4,12 +4,9 @@ import "CoreDSL-Instruction-Set-Description/RVC.core_desc" Core TGC_C provides RV32I, RV32M, RV32IC { architectural_state { - unsigned XLEN=32; - unsigned PCLEN=32; + XLEN=32; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA unsigned MISA_VAL = 0b01000000000000000001000100000100; - unsigned PGSIZE = 0x1000; //1 << 12; - unsigned PGMASK = 0xfff; //PGSIZE-1 } } diff --git a/gen_input/TGC_D.core_desc b/gen_input/TGC_D.core_desc index cf346b2..158f999 100644 --- a/gen_input/TGC_D.core_desc +++ b/gen_input/TGC_D.core_desc @@ -4,8 +4,7 @@ import "CoreDSL-Instruction-Set-Description/RVC.core_desc" Core TGC_D provides RV32I, RV32M, RV32IC { architectural_state { - unsigned XLEN=32; - unsigned PCLEN=32; + XLEN=32; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA unsigned MISA_VAL = 0b01000000000000000001000100000100; diff --git a/gen_input/TGC_D_XRB_MAC.core_desc b/gen_input/TGC_D_XRB_MAC.core_desc index dd4cfbe..0ab2c8d 100644 --- a/gen_input/TGC_D_XRB_MAC.core_desc +++ b/gen_input/TGC_D_XRB_MAC.core_desc @@ -64,8 +64,7 @@ InstructionSet X_RB_MAC extends RISCVBase { Core TGC_D_XRB_MAC provides RV32I, RV32M, RV32IC, X_RB_MAC { architectural_state { - unsigned XLEN=32; - unsigned PCLEN=32; + XLEN=32; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA unsigned MISA_VAL = 0b01000000000000000001000100000100; diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index 16fa1b4..8e5a728 100644 --- a/incl/iss/arch/tgc_c.h +++ b/incl/iss/arch/tgc_c.h @@ -51,9 +51,9 @@ template <> struct traits { {"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 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, 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; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index f2686de..f1ba0c5 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -467,8 +467,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 @@ -513,8 +518,13 @@ private: 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; + 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 @@ -557,7 +567,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(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); @@ -599,7 +614,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(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); @@ -641,7 +661,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(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); @@ -683,7 +708,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(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); @@ -725,7 +755,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(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); @@ -767,7 +802,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(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); From aa84a27a5b0609eb3159fca13b9bf4f3656956c9 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 29 Sep 2021 00:43:42 +0200 Subject: [PATCH 07/37] fix JALR alignment in description --- gen_input/CoreDSL-Instruction-Set-Description | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description index 89dabd0..9e3119a 160000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ b/gen_input/CoreDSL-Instruction-Set-Description @@ -1 +1 @@ -Subproject commit 89dabd00e3380d41070b126f8d6d1548056619c1 +Subproject commit 9e3119a8064e8515eeca7e5298f88d0d9d224458 From 17ee7b138d0a5ef8e182d71c5a1dd2dd273034ea Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 29 Sep 2021 00:44:17 +0200 Subject: [PATCH 08/37] update generated TGC-C VM --- src/vm/interp/vm_tgc_c.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index f1ba0c5..b1fceab 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -517,7 +517,7 @@ private: // execute instruction try { { - int32_t new_pc = *(X+rs1) + (int16_t)sext<12>(imm); + int32_t new_pc = (*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 1; if(new_pc % traits::INSTR_ALIGNMENT) { raise(0, 0); } From 4186723d37a82e76f6b9444fa89085e0c33089a5 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 30 Sep 2021 19:26:21 +0200 Subject: [PATCH 09/37] add marchid setting to CoreDSL description --- gen_input/TGC_B.core_desc | 1 + gen_input/TGC_C.core_desc | 1 + gen_input/TGC_D.core_desc | 1 + gen_input/TGC_D_XRB_MAC.core_desc | 1 + 4 files changed, 4 insertions(+) diff --git a/gen_input/TGC_B.core_desc b/gen_input/TGC_B.core_desc index 12263b9..78e86ec 100644 --- a/gen_input/TGC_B.core_desc +++ b/gen_input/TGC_B.core_desc @@ -8,6 +8,7 @@ Core TGC_B provides RV32I { // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA unsigned MISA_VAL = 0b01000000000000000000000100000000; + unsigned MARCHID_VAL = 0x80000002; } } diff --git a/gen_input/TGC_C.core_desc b/gen_input/TGC_C.core_desc index 93237ef..a8fed39 100644 --- a/gen_input/TGC_C.core_desc +++ b/gen_input/TGC_C.core_desc @@ -8,5 +8,6 @@ Core TGC_C provides RV32I, RV32M, RV32IC { // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA unsigned MISA_VAL = 0b01000000000000000001000100000100; + unsigned MARCHID_VAL = 0x80000003; } } diff --git a/gen_input/TGC_D.core_desc b/gen_input/TGC_D.core_desc index 158f999..9616296 100644 --- a/gen_input/TGC_D.core_desc +++ b/gen_input/TGC_D.core_desc @@ -8,5 +8,6 @@ Core TGC_D provides RV32I, RV32M, RV32IC { // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA unsigned MISA_VAL = 0b01000000000000000001000100000100; + unsigned MARCHID_VAL = 0x80000004; } } diff --git a/gen_input/TGC_D_XRB_MAC.core_desc b/gen_input/TGC_D_XRB_MAC.core_desc index 0ab2c8d..9968d56 100644 --- a/gen_input/TGC_D_XRB_MAC.core_desc +++ b/gen_input/TGC_D_XRB_MAC.core_desc @@ -68,5 +68,6 @@ Core TGC_D_XRB_MAC provides RV32I, RV32M, RV32IC, X_RB_MAC { // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA unsigned MISA_VAL = 0b01000000000000000001000100000100; + unsigned MARCHID_VAL = 0x80000004; } } From d78fcc48e54aef4ebffab1ceb079349b00fb44ef Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 30 Sep 2021 19:27:03 +0200 Subject: [PATCH 10/37] use marchid in platform --- incl/iss/arch/riscv_hart_m_p.h | 4 ++-- incl/iss/arch/riscv_hart_msu_vp.h | 2 +- incl/iss/arch/riscv_hart_mu_p.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 9d93bd2..406b946 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -307,7 +307,7 @@ riscv_hart_m_p::riscv_hart_m_p() // reset values csr[misa] = traits::MISA_VAL; csr[mvendorid] = 0x669; - csr[marchid] = 0x80000003; + csr[marchid] = traits::MARCHID_VAL; csr[mimpid] = 1; uart_buf.str(""); @@ -922,7 +922,7 @@ template uint64_t riscv_hart_m_p::enter_trap(uint64_t flag csr[mepc] = static_cast(addr) & get_pc_mask(); // store actual address instruction of exception switch(cause){ case 0: - csr[mtval] = instr; + csr[mtval] = addr; break; case 2: csr[mtval] = (instr & 0x3)==3?instr:instr&0xffff; diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index 2dbfef2..aa88e6d 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -419,7 +419,7 @@ riscv_hart_msu_vp::riscv_hart_msu_vp() // reset values csr[misa] = traits::MISA_VAL; csr[mvendorid] = 0x669; - csr[marchid] = 0x80000003; + csr[marchid] = traits::MARCHID_VAL; csr[mimpid] = 1; uart_buf.str(""); diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index b931fb2..b6ea430 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -349,7 +349,7 @@ riscv_hart_mu_p::riscv_hart_mu_p() // reset values csr[misa] = traits::MISA_VAL; csr[mvendorid] = 0x669; - csr[marchid] = 0x80000004; + csr[marchid] = traits::MARCHID_VAL; csr[mimpid] = 1; csr[mclicbase] = 0xc0000000; // TODO: should be taken from YAML file From 2f15d9676e850e891acf8af516198f9f18174db6 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 30 Sep 2021 19:27:46 +0200 Subject: [PATCH 11/37] fix unaligned instr fetch behavior --- gen_input/templates/interp/CORENAME.cpp.gtl | 3 - incl/iss/arch/tgc_c.h | 2 +- src/vm/interp/vm_tgc_c.cpp | 90 --------------------- 3 files changed, 1 insertion(+), 94 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index f2b86ae..c586317 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -65,8 +65,6 @@ public: using reg_t = typename traits::reg_t; using mem_type_e = typename traits::mem_type_e; - const bool has_compressed = traits::MISA_VAL & 0b100; - vm_impl(); vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); @@ -212,7 +210,6 @@ private: <%instr.behavior.eachLine{%>${it} <%}%>} catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx}); // trap check if(*trap_state!=0){ diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index 8e5a728..5a96c9e 100644 --- a/incl/iss/arch/tgc_c.h +++ b/incl/iss/arch/tgc_c.h @@ -53,7 +53,7 @@ template <> struct traits { static constexpr std::array 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"}}; - enum constants {MISA_VAL=0b01000000000000000001000100000100, XLEN=32, CSR_SIZE=4096, INSTR_ALIGNMENT=2, 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; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index b1fceab..715e3c9 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -65,8 +65,6 @@ public: using reg_t = typename traits::reg_t; using mem_type_e = typename traits::mem_type_e; - const bool has_compressed = traits::MISA_VAL & 0b100; - vm_impl(); vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); @@ -387,7 +385,6 @@ private: if(rd != 0) *(X+rd) = (int32_t)imm; } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 0); // trap check if(*trap_state!=0){ @@ -428,7 +425,6 @@ private: if(rd != 0) *(X+rd) = *PC + (int32_t)imm; } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 1); // trap check if(*trap_state!=0){ @@ -477,7 +473,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); // trap check if(*trap_state!=0){ @@ -528,7 +523,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3); // trap check if(*trap_state!=0){ @@ -575,7 +569,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); // trap check if(*trap_state!=0){ @@ -622,7 +615,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); // trap check if(*trap_state!=0){ @@ -669,7 +661,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); // trap check if(*trap_state!=0){ @@ -716,7 +707,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); // trap check if(*trap_state!=0){ @@ -763,7 +753,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); // trap check if(*trap_state!=0){ @@ -810,7 +799,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); // trap check if(*trap_state!=0){ @@ -855,7 +843,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10); // trap check if(*trap_state!=0){ @@ -901,7 +888,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11); // trap check if(*trap_state!=0){ @@ -947,7 +933,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12); // trap check if(*trap_state!=0){ @@ -992,7 +977,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13); // trap check if(*trap_state!=0){ @@ -1038,7 +1022,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14); // trap check if(*trap_state!=0){ @@ -1080,7 +1063,6 @@ private: writeSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2)); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); // trap check if(*trap_state!=0){ @@ -1125,7 +1107,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16); // trap check if(*trap_state!=0){ @@ -1170,7 +1151,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17); // trap check if(*trap_state!=0){ @@ -1212,7 +1192,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); // trap check if(*trap_state!=0){ @@ -1254,7 +1233,6 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); // trap check if(*trap_state!=0){ @@ -1296,7 +1274,6 @@ private: if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 20); // trap check if(*trap_state!=0){ @@ -1338,7 +1315,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); // trap check if(*trap_state!=0){ @@ -1380,7 +1356,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); // trap check if(*trap_state!=0){ @@ -1422,7 +1397,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); // trap check if(*trap_state!=0){ @@ -1469,7 +1443,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24); // trap check if(*trap_state!=0){ @@ -1516,7 +1489,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25); // trap check if(*trap_state!=0){ @@ -1563,7 +1535,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26); // trap check if(*trap_state!=0){ @@ -1605,7 +1576,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 27); // trap check if(*trap_state!=0){ @@ -1647,7 +1617,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 28); // trap check if(*trap_state!=0){ @@ -1689,7 +1658,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 29); // trap check if(*trap_state!=0){ @@ -1731,7 +1699,6 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 30); // trap check if(*trap_state!=0){ @@ -1773,7 +1740,6 @@ private: if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 31); // trap check if(*trap_state!=0){ @@ -1815,7 +1781,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 32); // trap check if(*trap_state!=0){ @@ -1857,7 +1822,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 33); // trap check if(*trap_state!=0){ @@ -1899,7 +1863,6 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 34); // trap check if(*trap_state!=0){ @@ -1941,7 +1904,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 35); // trap check if(*trap_state!=0){ @@ -1983,7 +1945,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 36); // trap check if(*trap_state!=0){ @@ -2026,7 +1987,6 @@ private: writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 37); // trap check if(*trap_state!=0){ @@ -2061,7 +2021,6 @@ private: raise(0, 11); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 38); // trap check if(*trap_state!=0){ @@ -2096,7 +2055,6 @@ private: raise(0, 3); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 39); // trap check if(*trap_state!=0){ @@ -2131,7 +2089,6 @@ private: leave(0); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 40); // trap check if(*trap_state!=0){ @@ -2166,7 +2123,6 @@ private: leave(1); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 41); // trap check if(*trap_state!=0){ @@ -2201,7 +2157,6 @@ private: leave(3); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 42); // trap check if(*trap_state!=0){ @@ -2236,7 +2191,6 @@ private: wait(1); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 43); // trap check if(*trap_state!=0){ @@ -2288,7 +2242,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); // trap check if(*trap_state!=0){ @@ -2335,7 +2288,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); // trap check if(*trap_state!=0){ @@ -2382,7 +2334,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); // trap check if(*trap_state!=0){ @@ -2428,7 +2379,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); // trap check if(*trap_state!=0){ @@ -2474,7 +2424,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); // trap check if(*trap_state!=0){ @@ -2520,7 +2469,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); // trap check if(*trap_state!=0){ @@ -2567,7 +2515,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); // trap check if(*trap_state!=0){ @@ -2614,7 +2561,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); // trap check if(*trap_state!=0){ @@ -2661,7 +2607,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); // trap check if(*trap_state!=0){ @@ -2708,7 +2653,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); // trap check if(*trap_state!=0){ @@ -2759,7 +2703,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); // trap check if(*trap_state!=0){ @@ -2806,7 +2749,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); // trap check if(*trap_state!=0){ @@ -2857,7 +2799,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); // trap check if(*trap_state!=0){ @@ -2904,7 +2845,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); // trap check if(*trap_state!=0){ @@ -2946,7 +2886,6 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); // trap check if(*trap_state!=0){ @@ -2991,7 +2930,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); // trap check if(*trap_state!=0){ @@ -3036,7 +2974,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); // trap check if(*trap_state!=0){ @@ -3077,7 +3014,6 @@ private: *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); // trap check if(*trap_state!=0){ @@ -3114,7 +3050,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); // trap check if(*trap_state!=0){ @@ -3157,7 +3092,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); // trap check if(*trap_state!=0){ @@ -3200,7 +3134,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); // trap check if(*trap_state!=0){ @@ -3244,7 +3177,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); // trap check if(*trap_state!=0){ @@ -3285,7 +3217,6 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); // trap check if(*trap_state!=0){ @@ -3321,7 +3252,6 @@ private: raise(0, 2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); // trap check if(*trap_state!=0){ @@ -3365,7 +3295,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); // trap check if(*trap_state!=0){ @@ -3413,7 +3342,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); // trap check if(*trap_state!=0){ @@ -3457,7 +3385,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); // trap check if(*trap_state!=0){ @@ -3501,7 +3428,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); // trap check if(*trap_state!=0){ @@ -3545,7 +3471,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); // trap check if(*trap_state!=0){ @@ -3589,7 +3514,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); // trap check if(*trap_state!=0){ @@ -3633,7 +3557,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); // trap check if(*trap_state!=0){ @@ -3672,7 +3595,6 @@ private: pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); // trap check if(*trap_state!=0){ @@ -3713,7 +3635,6 @@ private: if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); // trap check if(*trap_state!=0){ @@ -3754,7 +3675,6 @@ private: if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); // trap check if(*trap_state!=0){ @@ -3795,7 +3715,6 @@ private: if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); // trap check if(*trap_state!=0){ @@ -3840,7 +3759,6 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); // trap check if(*trap_state!=0){ @@ -3881,7 +3799,6 @@ private: if(rd != 0) *(X+rd) = *(X+rs2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); // trap check if(*trap_state!=0){ @@ -3922,7 +3839,6 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); // trap check if(*trap_state!=0){ @@ -3957,7 +3873,6 @@ private: raise(0, 2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); // trap check if(*trap_state!=0){ @@ -3998,7 +3913,6 @@ private: if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); // trap check if(*trap_state!=0){ @@ -4042,7 +3956,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); // trap check if(*trap_state!=0){ @@ -4077,7 +3990,6 @@ private: raise(0, 3); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); // trap check if(*trap_state!=0){ @@ -4121,7 +4033,6 @@ private: } } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); // trap check if(*trap_state!=0){ @@ -4156,7 +4067,6 @@ private: raise(0, 2); } catch(...){} // post execution stuff - if(!has_compressed && (*NEXT_PC&0x3)!=0) raise(0, 0); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); // trap check if(*trap_state!=0){ From 6acf73a40fc06b1371a8330c2ed0107cec84b36b Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 1 Oct 2021 13:05:36 +0200 Subject: [PATCH 12/37] add template to generate instruction YAML --- gen_input/templates/CORENAME_instr.yaml.gtl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 gen_input/templates/CORENAME_instr.yaml.gtl diff --git a/gen_input/templates/CORENAME_instr.yaml.gtl b/gen_input/templates/CORENAME_instr.yaml.gtl new file mode 100644 index 0000000..59fa845 --- /dev/null +++ b/gen_input/templates/CORENAME_instr.yaml.gtl @@ -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}<%}}%> + From 5866acf5657d3d4fed3f1bef85655b4a58efca1c Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 1 Oct 2021 13:06:10 +0200 Subject: [PATCH 13/37] update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 37563ca..cebb65a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ language.settings.xml /*.out /dump.json /src-gen/ +/*.yaml From b17682e50e72a7b15df347ca5d70343ccce9315d Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 1 Oct 2021 23:49:04 +0200 Subject: [PATCH 14/37] fix YAML template --- gen_input/templates/CORENAME_instr.yaml.gtl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen_input/templates/CORENAME_instr.yaml.gtl b/gen_input/templates/CORENAME_instr.yaml.gtl index 59fa845..122be5e 100644 --- a/gen_input/templates/CORENAME_instr.yaml.gtl +++ b/gen_input/templates/CORENAME_instr.yaml.gtl @@ -10,7 +10,7 @@ instrGroups }%><%getInstructionGroups().each{name, instrList -> %> ${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %> - - ${it.instruction.name} + - ${it.instruction.name}: encoding: ${it.encoding} mask: ${it.mask}<%}}%> From f0ada1ba8c13d31d3b0ec5bf621e86e507d5d241 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 10 Oct 2021 19:06:41 +0200 Subject: [PATCH 15/37] add MSVC 16 compatibility --- CMakeLists.txt | 23 +++++++++++++-------- incl/iss/arch/riscv_hart_m_p.h | 6 +++++- softfloat/build/Linux-x86_64-GCC/platform.h | 2 ++ src/main.cpp | 6 +++--- src/plugin/cycle_estimate.cpp | 12 ++++++----- src/plugin/instruction_count.cpp | 6 +++--- src/sysc/core_complex.cpp | 22 +++++++++++++------- src/vm/interp/vm_tgc_c.cpp | 12 +++++------ 8 files changed, 54 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5d7912..5878425 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,16 +48,22 @@ if(WITH_LLVM) endif() # Define the library -add_library(${PROJECT_NAME} SHARED ${LIB_SOURCES}) +add_library(${PROJECT_NAME} ${LIB_SOURCES}) # list code gen dependencies if(TARGET ${CORE_NAME}_cpp) add_dependencies(${PROJECT_NAME} ${CORE_NAME}_cpp) endif() -target_compile_options(${PROJECT_NAME} PRIVATE -Wno-shift-count-overflow) +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(${PROJECT_NAME} PRIVATE -Wno-shift-count-overflow) +endif() target_include_directories(${PROJECT_NAME} PUBLIC incl) target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp) -target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive) +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() if(TARGET CONAN_PKG::elfio) target_link_libraries(${PROJECT_NAME} PUBLIC CONAN_PKG::elfio) elseif(TARGET elfio::elfio) @@ -98,16 +104,15 @@ if(WITH_LLVM) target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs}) endif() # Links the target exe against the libraries -target_link_libraries(${PROJECT_NAME} dbt-rise-tgc) -#target_link_libraries(${PROJECT_NAME} jsoncpp) +target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc) if(TARGET Boost::program_options) - target_link_libraries(${PROJECT_NAME} Boost::program_options Boost::thread) + target_link_libraries(${PROJECT_NAME} PUBLIC Boost::program_options Boost::thread) else() - target_link_libraries(${PROJECT_NAME} ${BOOST_program_options_LIBRARY} ${BOOST_thread_LIBRARY}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY} ${BOOST_thread_LIBRARY}) endif() -target_link_libraries(${PROJECT_NAME} ${CMAKE_DL_LIBS}) +target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_DL_LIBS}) if (Tcmalloc_FOUND) - target_link_libraries(${PROJECT_NAME} ${Tcmalloc_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${Tcmalloc_LIBRARIES}) endif(Tcmalloc_FOUND) install(TARGETS tgc-sim diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 0104e2c..2a469e5 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -397,7 +397,7 @@ template std::pair riscv_hart_m_p::load_fi traits::MEM, pseg->get_physical_address(), fsize, reinterpret_cast(seg_data)); if (res != iss::Ok) - LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex + LOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex << pseg->get_physical_address(); } } @@ -948,7 +948,11 @@ template uint64_t riscv_hart_m_p::enter_trap(uint64_t flag this->reg.PRIV = PRIV_M; this->reg.trap_state = 0; std::array 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 << ")" diff --git a/softfloat/build/Linux-x86_64-GCC/platform.h b/softfloat/build/Linux-x86_64-GCC/platform.h index 337ca99..92c3044 100644 --- a/softfloat/build/Linux-x86_64-GCC/platform.h +++ b/softfloat/build/Linux-x86_64-GCC/platform.h @@ -49,7 +49,9 @@ 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" diff --git a/src/main.cpp b/src/main.cpp index ac139d1..dcab875 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -140,7 +140,7 @@ int main(int argc, char *argv[]) { } else #endif { - LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as() << std::endl; + LOG(ERR) << "Illegal argument value for '--isa': " << clim["isa"].as() << std::endl; return 127; } if (clim.count("plugin")) { @@ -161,7 +161,7 @@ int main(int argc, char *argv[]) { vm->register_plugin(*ce_plugin); plugin_list.push_back(ce_plugin); } else { - LOG(ERROR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl; + LOG(ERR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl; return 127; } } @@ -196,7 +196,7 @@ int main(int argc, char *argv[]) { auto cycles = clim["instructions"].as(); res = vm->start(cycles, dump); } catch (std::exception &e) { - LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" + LOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl; res = 2; } diff --git a/src/plugin/cycle_estimate.cpp b/src/plugin/cycle_estimate.cpp index 6abf77c..3aa856b 100644 --- a/src/plugin/cycle_estimate.cpp +++ b/src/plugin/cycle_estimate.cpp @@ -47,10 +47,10 @@ iss::plugin::cycle_estimate::cycle_estimate(std::string config_file_name) try { is >> root; } catch (Json::RuntimeError &e) { - LOG(ERROR) << "Could not parse input file " << config_file_name << ", reason: " << e.what(); + LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what(); } } else { - LOG(ERROR) << "Could not open input file " << config_file_name; + LOG(ERR) << "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(ERROR)<<"plugin cycle_estimate: could not find an entry for "<get_next_pc()-arch_instr->get_pc()) != (entry.size/8); - uint32_t delay = taken ? entry.taken : entry.not_taken; - if(delay>1) arch_instr->set_curr_instr_cycles(delay); + 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); } diff --git a/src/plugin/instruction_count.cpp b/src/plugin/instruction_count.cpp index 2f33d7c..aba30eb 100644 --- a/src/plugin/instruction_count.cpp +++ b/src/plugin/instruction_count.cpp @@ -46,10 +46,10 @@ iss::plugin::instruction_count::instruction_count(std::string config_file_name) try { is >> root; } catch (Json::RuntimeError &e) { - LOG(ERROR) << "Could not parse input file " << config_file_name << ", reason: " << e.what(); + LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what(); } } else { - LOG(ERROR) << "Could not open input file " << config_file_name; + LOG(ERR) << "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(ERROR)<<"plugin instruction_count: could not find an entry for "<; #include "iss/arch/tgc_d.h" using tgc_d_plat_type = iss::arch::riscv_hart_mu_p; #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 #include #include +// clang-format on #define STR(X) #X #define CREATE_CORE(CN) \ @@ -72,6 +74,12 @@ 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; @@ -287,7 +295,7 @@ public: CREATE_CORE(tgc_d) #endif { - LOG(ERROR) << "Illegal argument value for core type: " << type << std::endl; + LOG(ERR) << "Illegal argument value for core type: " << type << std::endl; } auto *srv = debugger::server::get(); if (srv) tgt_adapter = srv->get_target(); diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index e142646..a61fb17 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -30,23 +30,21 @@ * *******************************************************************************/ -#include "../fp_functions.h" -#include -#include +// clang-format off #include #include #include +#include +#include #include +#include "../fp_functions.h" #include #include - -#ifndef FMT_HEADER_ONLY -#define FMT_HEADER_ONLY -#endif #include #include #include +// clang-format on namespace iss { namespace interp { From c8679fca8550f513bb3dfb9bd67d1d1739735af0 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 10 Oct 2021 19:56:33 +0200 Subject: [PATCH 16/37] remove MSVC warning --- CMakeLists.txt | 6 ++++-- src/vm/interp/vm_tgc_c.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5878425..5098982 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,12 +54,14 @@ if(TARGET ${CORE_NAME}_cpp) add_dependencies(${PROJECT_NAME} ${CORE_NAME}_cpp) endif() -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") +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_include_directories(${PROJECT_NAME} PUBLIC incl) target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp) -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") +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) diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index a61fb17..70420ea 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -30,21 +30,21 @@ * *******************************************************************************/ -// clang-format off +// clang-format off #include #include #include -#include -#include +#include +#include #include -#include "../fp_functions.h" +#include "../fp_functions.h" #include #include #include #include #include -// clang-format on +// clang-format on namespace iss { namespace interp { From 1d13c8196e09c1b105bc8f2e6a2c5b4992f3bb1a Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 11 Oct 2021 10:40:01 +0200 Subject: [PATCH 17/37] fix wrong PGMASK usage --- gen_input/templates/interp/CORENAME.cpp.gtl | 2 +- src/vm/interp/vm_tgc_c.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index c586317..e3654d6 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -243,7 +243,7 @@ private: return pc; } - static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK; + //static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK; iss::status fetch_ins(virt_addr_t pc, uint8_t * data){ auto phys_pc = this->core.v2p(pc); //if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index e0dc71d..1cbb859 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -4098,7 +4098,6 @@ private: return pc; } - static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK; iss::status fetch_ins(virt_addr_t pc, uint8_t * data){ auto phys_pc = this->core.v2p(pc); //if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary From 0ea4cba1cadf2c6e7dde9090f17c74c0d7527ca5 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 12 Oct 2021 14:24:55 +0200 Subject: [PATCH 18/37] add dynamic plugin loading --- CMakeLists.txt | 16 ++++++++++----- incl/sysc/core_complex.h | 9 +++++++++ src/main.cpp | 16 +++++++++++++-- src/sysc/core_complex.cpp | 41 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5098982..6a7e14c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,11 +40,17 @@ set(LIB_SOURCES ) if(WITH_LLVM) - set(LIB_SOURCES ${LIB_SOURCES} - src/vm/llvm/fp_impl.cpp - #src/vm/llvm/vm_tgf_b.cpp - #src/vm/llvm/vm_tgf_c.cpp - ) + FILE(GLOB TGC_LLVM_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/llvm/vm_*.cpp + ) + list(APPEND LIB_SOURCES ${TGC_LLVM_SOURCES}) +endif() + +if(WITH_TCC) + FILE(GLOB TGC_TCC_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/tcc/vm_*.cpp + ) + list(APPEND LIB_SOURCES ${TGC_TCC_SOURCES}) endif() # Define the library diff --git a/incl/sysc/core_complex.h b/incl/sysc/core_complex.h index 4668837..33db30b 100644 --- a/incl/sysc/core_complex.h +++ b/incl/sysc/core_complex.h @@ -48,6 +48,9 @@ #include #include +namespace iss { + class vm_plugin; +} namespace sysc { class tlm_dmi_ext : public tlm::tlm_dmi { @@ -99,6 +102,8 @@ public: cci::cci_param mhartid{"mhartid", 0}; + cci::cci_param plugins{"plugins", ""}; + core_complex(sc_core::sc_module_name const& name); #else @@ -122,6 +127,8 @@ public: scml_property mhartid{"mhartid", 0}; + scml_property plugins{"plugins", ""}; + core_complex(sc_core::sc_module_name const& name) : sc_module(name) , local_irq_i{"local_irq_i", 16} @@ -185,6 +192,8 @@ protected: std::unique_ptr t2t; private: void init(); + std::vector plugin_list; + }; } /* namespace SiFive */ } /* namespace sysc */ diff --git a/src/main.cpp b/src/main.cpp index 5ccae24..358d4a1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -60,6 +60,10 @@ using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p #include #include +#include +#if defined(HAS_LUA) +#include +#endif namespace po = boost::program_options; @@ -172,8 +176,16 @@ 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; - return 127; + std::array a{{filename.c_str()}}; + iss::plugin::loader l(plugin_name, {{"initPlugin"}}); + auto* plugin = l.call_function("initPlugin", a.size(), a.data()); + if(plugin){ + vm->register_plugin(*plugin); + plugin_list.push_back(plugin); + } else { + LOG(ERR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl; + return 127; + } } } } diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index a304c82..fbe30e2 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -36,7 +36,8 @@ #include "iss/debugger/server.h" #include "iss/debugger/target_adapter_if.h" #include "iss/iss.h" -#include "iss/vm_types.h" +#include "iss/vm_types.h" +#include #include "sysc/core_complex.h" #ifdef CORE_TGC_B #include "iss/arch/riscv_hart_m_p.h" @@ -56,10 +57,13 @@ using tgc_d_plat_type = iss::arch::riscv_hart_mu_p; #endif -#include "scc/report.h" +#include +#include #include #include #include +#include +#include // clang-format on #define STR(X) #X @@ -380,6 +384,8 @@ void core_complex::init(){ core_complex::~core_complex(){ delete cpu; delete trc; + for (auto *p : plugin_list) + delete p; } void core_complex::trace(sc_trace_file *trf) const {} @@ -391,6 +397,37 @@ void core_complex::before_end_of_elaboration() { cpu->create_cpu(GET_PROP_VALUE(core_type), GET_PROP_VALUE(backend), GET_PROP_VALUE(gdb_server_port), GET_PROP_VALUE(mhartid)); sc_assert(cpu->vm!=nullptr); cpu->vm->setDisassEnabled(GET_PROP_VALUE(enable_disass) || trc->m_db != nullptr); + if (GET_PROP_VALUE(core_type).length()) { + auto p = util::split(GET_PROP_VALUE(plugins), ';'); + for (std::string const& opt_val : p) { + std::string plugin_name=opt_val; + std::string filename{"cycles.txt"}; + std::size_t found = opt_val.find('='); + if (found != std::string::npos) { + plugin_name = opt_val.substr(0, found); + filename = opt_val.substr(found + 1, opt_val.size()); + } + if (plugin_name == "ic") { + auto *plugin = new iss::plugin::instruction_count(filename); + cpu->vm->register_plugin(*plugin); + plugin_list.push_back(plugin); + } else if (plugin_name == "ce") { + auto *plugin = new iss::plugin::cycle_estimate(filename); + cpu->vm->register_plugin(*plugin); + plugin_list.push_back(plugin); + } else { + std::array a{{filename.c_str()}}; + iss::plugin::loader l(plugin_name, {{"initPlugin"}}); + auto* plugin = l.call_function("initPlugin", a.size(), a.data()); + if(plugin){ + cpu->vm->register_plugin(*plugin); + plugin_list.push_back(plugin); + } else + SCCERR(SCMOD) << "Unknown plugin '" << plugin_name << "' or plugin not found"; + } + } + } + } void core_complex::start_of_simulation() { From eb2ca33e5acac87259aeca784bf700ea9499cb0e Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 12 Oct 2021 15:17:56 +0200 Subject: [PATCH 19/37] remove unused sources --- src/plugin/GCOV.cpp | 821 -------------------------------------------- src/plugin/GCOV.h | 460 ------------------------- 2 files changed, 1281 deletions(-) delete mode 100644 src/plugin/GCOV.cpp delete mode 100644 src/plugin/GCOV.h diff --git a/src/plugin/GCOV.cpp b/src/plugin/GCOV.cpp deleted file mode 100644 index 6ce6440..0000000 --- a/src/plugin/GCOV.cpp +++ /dev/null @@ -1,821 +0,0 @@ -//===- GCOV.cpp - LLVM coverage tool --------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// GCOV implements the interface to read and write coverage files that use -// 'gcov' format. -// -//===----------------------------------------------------------------------===// - -#include "GCOV.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" -#include -#include - -using namespace llvm; - -//===----------------------------------------------------------------------===// -// GCOVFile implementation. - -/// readGCNO - Read GCNO buffer. -bool GCOVFile::readGCNO(GCOVBuffer &Buffer) { - if (!Buffer.readGCNOFormat()) - return false; - if (!Buffer.readGCOVVersion(Version)) - return false; - - if (!Buffer.readInt(Checksum)) - return false; - while (true) { - if (!Buffer.readFunctionTag()) - break; - auto GFun = make_unique(*this); - if (!GFun->readGCNO(Buffer, Version)) - return false; - Functions.push_back(std::move(GFun)); - } - - GCNOInitialized = true; - return true; -} - -/// readGCDA - Read GCDA buffer. It is required that readGCDA() can only be -/// called after readGCNO(). -bool GCOVFile::readGCDA(GCOVBuffer &Buffer) { - assert(GCNOInitialized && "readGCDA() can only be called after readGCNO()"); - if (!Buffer.readGCDAFormat()) - return false; - GCOV::GCOVVersion GCDAVersion; - if (!Buffer.readGCOVVersion(GCDAVersion)) - return false; - if (Version != GCDAVersion) { - errs() << "GCOV versions do not match.\n"; - return false; - } - - uint32_t GCDAChecksum; - if (!Buffer.readInt(GCDAChecksum)) - return false; - if (Checksum != GCDAChecksum) { - errs() << "File checksums do not match: " << Checksum - << " != " << GCDAChecksum << ".\n"; - return false; - } - for (size_t i = 0, e = Functions.size(); i < e; ++i) { - if (!Buffer.readFunctionTag()) { - errs() << "Unexpected number of functions.\n"; - return false; - } - if (!Functions[i]->readGCDA(Buffer, Version)) - return false; - } - if (Buffer.readObjectTag()) { - uint32_t Length; - uint32_t Dummy; - if (!Buffer.readInt(Length)) - return false; - if (!Buffer.readInt(Dummy)) - return false; // checksum - if (!Buffer.readInt(Dummy)) - return false; // num - if (!Buffer.readInt(RunCount)) - return false; - Buffer.advanceCursor(Length - 3); - } - while (Buffer.readProgramTag()) { - uint32_t Length; - if (!Buffer.readInt(Length)) - return false; - Buffer.advanceCursor(Length); - ++ProgramCount; - } - - return true; -} - -void GCOVFile::print(raw_ostream &OS) const { - for (const auto &FPtr : Functions) - FPtr->print(OS); -} - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -/// dump - Dump GCOVFile content to dbgs() for debugging purposes. -LLVM_DUMP_METHOD void GCOVFile::dump() const { - print(dbgs()); -} -#endif - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVFile::collectLineCounts(FileInfo &FI) { - for (const auto &FPtr : Functions) - FPtr->collectLineCounts(FI); - FI.setRunCount(RunCount); - FI.setProgramCount(ProgramCount); -} - -//===----------------------------------------------------------------------===// -// GCOVFunction implementation. - -/// readGCNO - Read a function from the GCNO buffer. Return false if an error -/// occurs. -bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) { - uint32_t Dummy; - if (!Buff.readInt(Dummy)) - return false; // Function header length - if (!Buff.readInt(Ident)) - return false; - if (!Buff.readInt(Checksum)) - return false; - if (Version != GCOV::V402) { - uint32_t CfgChecksum; - if (!Buff.readInt(CfgChecksum)) - return false; - if (Parent.getChecksum() != CfgChecksum) { - errs() << "File checksums do not match: " << Parent.getChecksum() - << " != " << CfgChecksum << " in (" << Name << ").\n"; - return false; - } - } - if (!Buff.readString(Name)) - return false; - if (!Buff.readString(Filename)) - return false; - if (!Buff.readInt(LineNumber)) - return false; - - // read blocks. - if (!Buff.readBlockTag()) { - errs() << "Block tag not found.\n"; - return false; - } - uint32_t BlockCount; - if (!Buff.readInt(BlockCount)) - return false; - for (uint32_t i = 0, e = BlockCount; i != e; ++i) { - if (!Buff.readInt(Dummy)) - return false; // Block flags; - Blocks.push_back(make_unique(*this, i)); - } - - // read edges. - while (Buff.readEdgeTag()) { - uint32_t EdgeCount; - if (!Buff.readInt(EdgeCount)) - return false; - EdgeCount = (EdgeCount - 1) / 2; - uint32_t BlockNo; - if (!Buff.readInt(BlockNo)) - return false; - if (BlockNo >= BlockCount) { - errs() << "Unexpected block number: " << BlockNo << " (in " << Name - << ").\n"; - return false; - } - for (uint32_t i = 0, e = EdgeCount; i != e; ++i) { - uint32_t Dst; - if (!Buff.readInt(Dst)) - return false; - Edges.push_back(make_unique(*Blocks[BlockNo], *Blocks[Dst])); - GCOVEdge *Edge = Edges.back().get(); - Blocks[BlockNo]->addDstEdge(Edge); - Blocks[Dst]->addSrcEdge(Edge); - if (!Buff.readInt(Dummy)) - return false; // Edge flag - } - } - - // read line table. - while (Buff.readLineTag()) { - uint32_t LineTableLength; - // Read the length of this line table. - if (!Buff.readInt(LineTableLength)) - return false; - uint32_t EndPos = Buff.getCursor() + LineTableLength * 4; - uint32_t BlockNo; - // Read the block number this table is associated with. - if (!Buff.readInt(BlockNo)) - return false; - if (BlockNo >= BlockCount) { - errs() << "Unexpected block number: " << BlockNo << " (in " << Name - << ").\n"; - return false; - } - GCOVBlock &Block = *Blocks[BlockNo]; - // Read the word that pads the beginning of the line table. This may be a - // flag of some sort, but seems to always be zero. - if (!Buff.readInt(Dummy)) - return false; - - // Line information starts here and continues up until the last word. - if (Buff.getCursor() != (EndPos - sizeof(uint32_t))) { - StringRef F; - // Read the source file name. - if (!Buff.readString(F)) - return false; - if (Filename != F) { - errs() << "Multiple sources for a single basic block: " << Filename - << " != " << F << " (in " << Name << ").\n"; - return false; - } - // Read lines up to, but not including, the null terminator. - while (Buff.getCursor() < (EndPos - 2 * sizeof(uint32_t))) { - uint32_t Line; - if (!Buff.readInt(Line)) - return false; - // Line 0 means this instruction was injected by the compiler. Skip it. - if (!Line) - continue; - Block.addLine(Line); - } - // Read the null terminator. - if (!Buff.readInt(Dummy)) - return false; - } - // The last word is either a flag or padding, it isn't clear which. Skip - // over it. - if (!Buff.readInt(Dummy)) - return false; - } - return true; -} - -/// readGCDA - Read a function from the GCDA buffer. Return false if an error -/// occurs. -bool GCOVFunction::readGCDA(GCOVBuffer &Buff, GCOV::GCOVVersion Version) { - uint32_t HeaderLength; - if (!Buff.readInt(HeaderLength)) - return false; // Function header length - - uint64_t EndPos = Buff.getCursor() + HeaderLength * sizeof(uint32_t); - - uint32_t GCDAIdent; - if (!Buff.readInt(GCDAIdent)) - return false; - if (Ident != GCDAIdent) { - errs() << "Function identifiers do not match: " << Ident - << " != " << GCDAIdent << " (in " << Name << ").\n"; - return false; - } - - uint32_t GCDAChecksum; - if (!Buff.readInt(GCDAChecksum)) - return false; - if (Checksum != GCDAChecksum) { - errs() << "Function checksums do not match: " << Checksum - << " != " << GCDAChecksum << " (in " << Name << ").\n"; - return false; - } - - uint32_t CfgChecksum; - if (Version != GCOV::V402) { - if (!Buff.readInt(CfgChecksum)) - return false; - if (Parent.getChecksum() != CfgChecksum) { - errs() << "File checksums do not match: " << Parent.getChecksum() - << " != " << CfgChecksum << " (in " << Name << ").\n"; - return false; - } - } - - if (Buff.getCursor() < EndPos) { - StringRef GCDAName; - if (!Buff.readString(GCDAName)) - return false; - if (Name != GCDAName) { - errs() << "Function names do not match: " << Name << " != " << GCDAName - << ".\n"; - return false; - } - } - - if (!Buff.readArcTag()) { - errs() << "Arc tag not found (in " << Name << ").\n"; - return false; - } - - uint32_t Count; - if (!Buff.readInt(Count)) - return false; - Count /= 2; - - // This for loop adds the counts for each block. A second nested loop is - // required to combine the edge counts that are contained in the GCDA file. - for (uint32_t BlockNo = 0; Count > 0; ++BlockNo) { - // The last block is always reserved for exit block - if (BlockNo >= Blocks.size()) { - errs() << "Unexpected number of edges (in " << Name << ").\n"; - return false; - } - if (BlockNo == Blocks.size() - 1) - errs() << "(" << Name << ") has arcs from exit block.\n"; - GCOVBlock &Block = *Blocks[BlockNo]; - for (size_t EdgeNo = 0, End = Block.getNumDstEdges(); EdgeNo < End; - ++EdgeNo) { - if (Count == 0) { - errs() << "Unexpected number of edges (in " << Name << ").\n"; - return false; - } - uint64_t ArcCount; - if (!Buff.readInt64(ArcCount)) - return false; - Block.addCount(EdgeNo, ArcCount); - --Count; - } - Block.sortDstEdges(); - } - return true; -} - -/// getEntryCount - Get the number of times the function was called by -/// retrieving the entry block's count. -uint64_t GCOVFunction::getEntryCount() const { - return Blocks.front()->getCount(); -} - -/// getExitCount - Get the number of times the function returned by retrieving -/// the exit block's count. -uint64_t GCOVFunction::getExitCount() const { - return Blocks.back()->getCount(); -} - -void GCOVFunction::print(raw_ostream &OS) const { - OS << "===== " << Name << " (" << Ident << ") @ " << Filename << ":" - << LineNumber << "\n"; - for (const auto &Block : Blocks) - Block->print(OS); -} - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -/// dump - Dump GCOVFunction content to dbgs() for debugging purposes. -LLVM_DUMP_METHOD void GCOVFunction::dump() const { - print(dbgs()); -} -#endif - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVFunction::collectLineCounts(FileInfo &FI) { - // If the line number is zero, this is a function that doesn't actually appear - // in the source file, so there isn't anything we can do with it. - if (LineNumber == 0) - return; - - for (const auto &Block : Blocks) - Block->collectLineCounts(FI); - FI.addFunctionLine(Filename, LineNumber, this); -} - -//===----------------------------------------------------------------------===// -// GCOVBlock implementation. - -/// ~GCOVBlock - Delete GCOVBlock and its content. -GCOVBlock::~GCOVBlock() { - SrcEdges.clear(); - DstEdges.clear(); - Lines.clear(); -} - -/// addCount - Add to block counter while storing the edge count. If the -/// destination has no outgoing edges, also update that block's count too. -void GCOVBlock::addCount(size_t DstEdgeNo, uint64_t N) { - assert(DstEdgeNo < DstEdges.size()); // up to caller to ensure EdgeNo is valid - DstEdges[DstEdgeNo]->Count = N; - Counter += N; - if (!DstEdges[DstEdgeNo]->Dst.getNumDstEdges()) - DstEdges[DstEdgeNo]->Dst.Counter += N; -} - -/// sortDstEdges - Sort destination edges by block number, nop if already -/// sorted. This is required for printing branch info in the correct order. -void GCOVBlock::sortDstEdges() { - if (!DstEdgesAreSorted) { - SortDstEdgesFunctor SortEdges; - std::stable_sort(DstEdges.begin(), DstEdges.end(), SortEdges); - } -} - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVBlock::collectLineCounts(FileInfo &FI) { - for (uint32_t N : Lines) - FI.addBlockLine(Parent.getFilename(), N, this); -} - -void GCOVBlock::print(raw_ostream &OS) const { - OS << "Block : " << Number << " Counter : " << Counter << "\n"; - if (!SrcEdges.empty()) { - OS << "\tSource Edges : "; - for (const GCOVEdge *Edge : SrcEdges) - OS << Edge->Src.Number << " (" << Edge->Count << "), "; - OS << "\n"; - } - if (!DstEdges.empty()) { - OS << "\tDestination Edges : "; - for (const GCOVEdge *Edge : DstEdges) - OS << Edge->Dst.Number << " (" << Edge->Count << "), "; - OS << "\n"; - } - if (!Lines.empty()) { - OS << "\tLines : "; - for (uint32_t N : Lines) - OS << (N) << ","; - OS << "\n"; - } -} - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -/// dump - Dump GCOVBlock content to dbgs() for debugging purposes. -LLVM_DUMP_METHOD void GCOVBlock::dump() const { - print(dbgs()); -} -#endif - -//===----------------------------------------------------------------------===// -// FileInfo implementation. - -// Safe integer division, returns 0 if numerator is 0. -static uint32_t safeDiv(uint64_t Numerator, uint64_t Divisor) { - if (!Numerator) - return 0; - return Numerator / Divisor; -} - -// This custom division function mimics gcov's branch ouputs: -// - Round to closest whole number -// - Only output 0% or 100% if it's exactly that value -static uint32_t branchDiv(uint64_t Numerator, uint64_t Divisor) { - if (!Numerator) - return 0; - if (Numerator == Divisor) - return 100; - - uint8_t Res = (Numerator * 100 + Divisor / 2) / Divisor; - if (Res == 0) - return 1; - if (Res == 100) - return 99; - return Res; -} - -namespace { -struct formatBranchInfo { - formatBranchInfo(const GCOV::Options &Options, uint64_t Count, uint64_t Total) - : Options(Options), Count(Count), Total(Total) {} - - void print(raw_ostream &OS) const { - if (!Total) - OS << "never executed"; - else if (Options.BranchCount) - OS << "taken " << Count; - else - OS << "taken " << branchDiv(Count, Total) << "%"; - } - - const GCOV::Options &Options; - uint64_t Count; - uint64_t Total; -}; - -static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) { - FBI.print(OS); - return OS; -} - -class LineConsumer { - std::unique_ptr Buffer; - StringRef Remaining; - -public: - LineConsumer(StringRef Filename) { - ErrorOr> BufferOrErr = - MemoryBuffer::getFileOrSTDIN(Filename); - if (std::error_code EC = BufferOrErr.getError()) { - errs() << Filename << ": " << EC.message() << "\n"; - Remaining = ""; - } else { - Buffer = std::move(BufferOrErr.get()); - Remaining = Buffer->getBuffer(); - } - } - bool empty() { return Remaining.empty(); } - void printNext(raw_ostream &OS, uint32_t LineNum) { - StringRef Line; - if (empty()) - Line = "/*EOF*/"; - else - std::tie(Line, Remaining) = Remaining.split("\n"); - OS << format("%5u:", LineNum) << Line << "\n"; - } -}; -} // end anonymous namespace - -/// Convert a path to a gcov filename. If PreservePaths is true, this -/// translates "/" to "#", ".." to "^", and drops ".", to match gcov. -static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) { - if (!PreservePaths) - return sys::path::filename(Filename).str(); - - // This behaviour is defined by gcov in terms of text replacements, so it's - // not likely to do anything useful on filesystems with different textual - // conventions. - llvm::SmallString<256> Result(""); - StringRef::iterator I, S, E; - for (I = S = Filename.begin(), E = Filename.end(); I != E; ++I) { - if (*I != '/') - continue; - - if (I - S == 1 && *S == '.') { - // ".", the current directory, is skipped. - } else if (I - S == 2 && *S == '.' && *(S + 1) == '.') { - // "..", the parent directory, is replaced with "^". - Result.append("^#"); - } else { - if (S < I) - // Leave other components intact, - Result.append(S, I); - // And separate with "#". - Result.push_back('#'); - } - S = I + 1; - } - - if (S < I) - Result.append(S, I); - return Result.str(); -} - -std::string FileInfo::getCoveragePath(StringRef Filename, - StringRef MainFilename) { - if (Options.NoOutput) - // This is probably a bug in gcov, but when -n is specified, paths aren't - // mangled at all, and the -l and -p options are ignored. Here, we do the - // same. - return Filename; - - std::string CoveragePath; - if (Options.LongFileNames && !Filename.equals(MainFilename)) - CoveragePath = - mangleCoveragePath(MainFilename, Options.PreservePaths) + "##"; - CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths) + ".gcov"; - return CoveragePath; -} - -std::unique_ptr -FileInfo::openCoveragePath(StringRef CoveragePath) { - if (Options.NoOutput) - return llvm::make_unique(); - - std::error_code EC; - auto OS = llvm::make_unique(CoveragePath, EC, - sys::fs::F_Text); - if (EC) { - errs() << EC.message() << "\n"; - return llvm::make_unique(); - } - return std::move(OS); -} - -/// print - Print source files with collected line count information. -void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename, - StringRef GCNOFile, StringRef GCDAFile) { - SmallVector Filenames; - for (const auto &LI : LineInfo) - Filenames.push_back(LI.first()); - std::sort(Filenames.begin(), Filenames.end()); - - for (StringRef Filename : Filenames) { - auto AllLines = LineConsumer(Filename); - - std::string CoveragePath = getCoveragePath(Filename, MainFilename); - std::unique_ptr CovStream = openCoveragePath(CoveragePath); - raw_ostream &CovOS = *CovStream; - - CovOS << " -: 0:Source:" << Filename << "\n"; - CovOS << " -: 0:Graph:" << GCNOFile << "\n"; - CovOS << " -: 0:Data:" << GCDAFile << "\n"; - CovOS << " -: 0:Runs:" << RunCount << "\n"; - CovOS << " -: 0:Programs:" << ProgramCount << "\n"; - - const LineData &Line = LineInfo[Filename]; - GCOVCoverage FileCoverage(Filename); - for (uint32_t LineIndex = 0; LineIndex < Line.LastLine || !AllLines.empty(); - ++LineIndex) { - if (Options.BranchInfo) { - FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex); - if (FuncsIt != Line.Functions.end()) - printFunctionSummary(CovOS, FuncsIt->second); - } - - BlockLines::const_iterator BlocksIt = Line.Blocks.find(LineIndex); - if (BlocksIt == Line.Blocks.end()) { - // No basic blocks are on this line. Not an executable line of code. - CovOS << " -:"; - AllLines.printNext(CovOS, LineIndex + 1); - } else { - const BlockVector &Blocks = BlocksIt->second; - - // Add up the block counts to form line counts. - DenseMap LineExecs; - uint64_t LineCount = 0; - for (const GCOVBlock *Block : Blocks) { - if (Options.AllBlocks) { - // Only take the highest block count for that line. - uint64_t BlockCount = Block->getCount(); - LineCount = LineCount > BlockCount ? LineCount : BlockCount; - } else { - // Sum up all of the block counts. - LineCount += Block->getCount(); - } - - if (Options.FuncCoverage) { - // This is a slightly convoluted way to most accurately gather line - // statistics for functions. Basically what is happening is that we - // don't want to count a single line with multiple blocks more than - // once. However, we also don't simply want to give the total line - // count to every function that starts on the line. Thus, what is - // happening here are two things: - // 1) Ensure that the number of logical lines is only incremented - // once per function. - // 2) If there are multiple blocks on the same line, ensure that the - // number of lines executed is incremented as long as at least - // one of the blocks are executed. - const GCOVFunction *Function = &Block->getParent(); - if (FuncCoverages.find(Function) == FuncCoverages.end()) { - std::pair KeyValue( - Function, GCOVCoverage(Function->getName())); - FuncCoverages.insert(KeyValue); - } - GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second; - - if (LineExecs.find(Function) == LineExecs.end()) { - if (Block->getCount()) { - ++FuncCoverage.LinesExec; - LineExecs[Function] = true; - } else { - LineExecs[Function] = false; - } - ++FuncCoverage.LogicalLines; - } else if (!LineExecs[Function] && Block->getCount()) { - ++FuncCoverage.LinesExec; - LineExecs[Function] = true; - } - } - } - - if (LineCount == 0) - CovOS << " #####:"; - else { - CovOS << format("%9" PRIu64 ":", LineCount); - ++FileCoverage.LinesExec; - } - ++FileCoverage.LogicalLines; - - AllLines.printNext(CovOS, LineIndex + 1); - - uint32_t BlockNo = 0; - uint32_t EdgeNo = 0; - for (const GCOVBlock *Block : Blocks) { - // Only print block and branch information at the end of the block. - if (Block->getLastLine() != LineIndex + 1) - continue; - if (Options.AllBlocks) - printBlockInfo(CovOS, *Block, LineIndex, BlockNo); - if (Options.BranchInfo) { - size_t NumEdges = Block->getNumDstEdges(); - if (NumEdges > 1) - printBranchInfo(CovOS, *Block, FileCoverage, EdgeNo); - else if (Options.UncondBranch && NumEdges == 1) - printUncondBranchInfo(CovOS, EdgeNo, - (*Block->dst_begin())->Count); - } - } - } - } - FileCoverages.push_back(std::make_pair(CoveragePath, FileCoverage)); - } - - // FIXME: There is no way to detect calls given current instrumentation. - if (Options.FuncCoverage) - printFuncCoverage(InfoOS); - printFileCoverage(InfoOS); -} - -/// printFunctionSummary - Print function and block summary. -void FileInfo::printFunctionSummary(raw_ostream &OS, - const FunctionVector &Funcs) const { - for (const GCOVFunction *Func : Funcs) { - uint64_t EntryCount = Func->getEntryCount(); - uint32_t BlocksExec = 0; - for (const GCOVBlock &Block : Func->blocks()) - if (Block.getNumDstEdges() && Block.getCount()) - ++BlocksExec; - - OS << "function " << Func->getName() << " called " << EntryCount - << " returned " << safeDiv(Func->getExitCount() * 100, EntryCount) - << "% blocks executed " - << safeDiv(BlocksExec * 100, Func->getNumBlocks() - 1) << "%\n"; - } -} - -/// printBlockInfo - Output counts for each block. -void FileInfo::printBlockInfo(raw_ostream &OS, const GCOVBlock &Block, - uint32_t LineIndex, uint32_t &BlockNo) const { - if (Block.getCount() == 0) - OS << " $$$$$:"; - else - OS << format("%9" PRIu64 ":", Block.getCount()); - OS << format("%5u-block %2u\n", LineIndex + 1, BlockNo++); -} - -/// printBranchInfo - Print conditional branch probabilities. -void FileInfo::printBranchInfo(raw_ostream &OS, const GCOVBlock &Block, - GCOVCoverage &Coverage, uint32_t &EdgeNo) { - SmallVector BranchCounts; - uint64_t TotalCounts = 0; - for (const GCOVEdge *Edge : Block.dsts()) { - BranchCounts.push_back(Edge->Count); - TotalCounts += Edge->Count; - if (Block.getCount()) - ++Coverage.BranchesExec; - if (Edge->Count) - ++Coverage.BranchesTaken; - ++Coverage.Branches; - - if (Options.FuncCoverage) { - const GCOVFunction *Function = &Block.getParent(); - GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second; - if (Block.getCount()) - ++FuncCoverage.BranchesExec; - if (Edge->Count) - ++FuncCoverage.BranchesTaken; - ++FuncCoverage.Branches; - } - } - - for (uint64_t N : BranchCounts) - OS << format("branch %2u ", EdgeNo++) - << formatBranchInfo(Options, N, TotalCounts) << "\n"; -} - -/// printUncondBranchInfo - Print unconditional branch probabilities. -void FileInfo::printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo, - uint64_t Count) const { - OS << format("unconditional %2u ", EdgeNo++) - << formatBranchInfo(Options, Count, Count) << "\n"; -} - -// printCoverage - Print generic coverage info used by both printFuncCoverage -// and printFileCoverage. -void FileInfo::printCoverage(raw_ostream &OS, - const GCOVCoverage &Coverage) const { - OS << format("Lines executed:%.2f%% of %u\n", - double(Coverage.LinesExec) * 100 / Coverage.LogicalLines, - Coverage.LogicalLines); - if (Options.BranchInfo) { - if (Coverage.Branches) { - OS << format("Branches executed:%.2f%% of %u\n", - double(Coverage.BranchesExec) * 100 / Coverage.Branches, - Coverage.Branches); - OS << format("Taken at least once:%.2f%% of %u\n", - double(Coverage.BranchesTaken) * 100 / Coverage.Branches, - Coverage.Branches); - } else { - OS << "No branches\n"; - } - OS << "No calls\n"; // to be consistent with gcov - } -} - -// printFuncCoverage - Print per-function coverage info. -void FileInfo::printFuncCoverage(raw_ostream &OS) const { - for (const auto &FC : FuncCoverages) { - const GCOVCoverage &Coverage = FC.second; - OS << "Function '" << Coverage.Name << "'\n"; - printCoverage(OS, Coverage); - OS << "\n"; - } -} - -// printFileCoverage - Print per-file coverage info. -void FileInfo::printFileCoverage(raw_ostream &OS) const { - for (const auto &FC : FileCoverages) { - const std::string &Filename = FC.first; - const GCOVCoverage &Coverage = FC.second; - OS << "File '" << Coverage.Name << "'\n"; - printCoverage(OS, Coverage); - if (!Options.NoOutput) - OS << Coverage.Name << ":creating '" << Filename << "'\n"; - OS << "\n"; - } -} diff --git a/src/plugin/GCOV.h b/src/plugin/GCOV.h deleted file mode 100644 index 497f80b..0000000 --- a/src/plugin/GCOV.h +++ /dev/null @@ -1,460 +0,0 @@ -//===- GCOV.h - LLVM coverage tool ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header provides the interface to read and write coverage files that -// use 'gcov' format. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_PROFILEDATA_GCOV_H -#define LLVM_PROFILEDATA_GCOV_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/MapVector.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/iterator.h" -#include "llvm/ADT/iterator_range.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include -#include -#include - -namespace llvm { - -class GCOVFunction; -class GCOVBlock; -class FileInfo; - -namespace GCOV { - -enum GCOVVersion { V402, V404, V704 }; - -/// \brief A struct for passing gcov options between functions. -struct Options { - Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N) - : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F), - PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N) {} - - bool AllBlocks; - bool BranchInfo; - bool BranchCount; - bool FuncCoverage; - bool PreservePaths; - bool UncondBranch; - bool LongFileNames; - bool NoOutput; -}; - -} // end namespace GCOV - -/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific -/// read operations. -class GCOVBuffer { -public: - GCOVBuffer(MemoryBuffer *B) : Buffer(B) {} - - /// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer. - bool readGCNOFormat() { - StringRef File = Buffer->getBuffer().slice(0, 4); - if (File != "oncg") { - errs() << "Unexpected file type: " << File << ".\n"; - return false; - } - Cursor = 4; - return true; - } - - /// readGCDAFormat - Check GCDA signature is valid at the beginning of buffer. - bool readGCDAFormat() { - StringRef File = Buffer->getBuffer().slice(0, 4); - if (File != "adcg") { - errs() << "Unexpected file type: " << File << ".\n"; - return false; - } - Cursor = 4; - return true; - } - - /// readGCOVVersion - Read GCOV version. - bool readGCOVVersion(GCOV::GCOVVersion &Version) { - StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor + 4); - if (VersionStr == "*204") { - Cursor += 4; - Version = GCOV::V402; - return true; - } - if (VersionStr == "*404") { - Cursor += 4; - Version = GCOV::V404; - return true; - } - if (VersionStr == "*704") { - Cursor += 4; - Version = GCOV::V704; - return true; - } - errs() << "Unexpected version: " << VersionStr << ".\n"; - return false; - } - - /// readFunctionTag - If cursor points to a function tag then increment the - /// cursor and return true otherwise return false. - bool readFunctionTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); - if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' || - Tag[3] != '\1') { - return false; - } - Cursor += 4; - return true; - } - - /// readBlockTag - If cursor points to a block tag then increment the - /// cursor and return true otherwise return false. - bool readBlockTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); - if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x41' || - Tag[3] != '\x01') { - return false; - } - Cursor += 4; - return true; - } - - /// readEdgeTag - If cursor points to an edge tag then increment the - /// cursor and return true otherwise return false. - bool readEdgeTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); - if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x43' || - Tag[3] != '\x01') { - return false; - } - Cursor += 4; - return true; - } - - /// readLineTag - If cursor points to a line tag then increment the - /// cursor and return true otherwise return false. - bool readLineTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); - if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x45' || - Tag[3] != '\x01') { - return false; - } - Cursor += 4; - return true; - } - - /// readArcTag - If cursor points to an gcda arc tag then increment the - /// cursor and return true otherwise return false. - bool readArcTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); - if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\xa1' || - Tag[3] != '\1') { - return false; - } - Cursor += 4; - return true; - } - - /// readObjectTag - If cursor points to an object summary tag then increment - /// the cursor and return true otherwise return false. - bool readObjectTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); - if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' || - Tag[3] != '\xa1') { - return false; - } - Cursor += 4; - return true; - } - - /// readProgramTag - If cursor points to a program summary tag then increment - /// the cursor and return true otherwise return false. - bool readProgramTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); - if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' || - Tag[3] != '\xa3') { - return false; - } - Cursor += 4; - return true; - } - - bool readInt(uint32_t &Val) { - if (Buffer->getBuffer().size() < Cursor + 4) { - errs() << "Unexpected end of memory buffer: " << Cursor + 4 << ".\n"; - return false; - } - StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor + 4); - Cursor += 4; - Val = *(const uint32_t *)(Str.data()); - return true; - } - - bool readInt64(uint64_t &Val) { - uint32_t Lo, Hi; - if (!readInt(Lo) || !readInt(Hi)) - return false; - Val = ((uint64_t)Hi << 32) | Lo; - return true; - } - - bool readString(StringRef &Str) { - uint32_t Len = 0; - // Keep reading until we find a non-zero length. This emulates gcov's - // behaviour, which appears to do the same. - while (Len == 0) - if (!readInt(Len)) - return false; - Len *= 4; - if (Buffer->getBuffer().size() < Cursor + Len) { - errs() << "Unexpected end of memory buffer: " << Cursor + Len << ".\n"; - return false; - } - Str = Buffer->getBuffer().slice(Cursor, Cursor + Len).split('\0').first; - Cursor += Len; - return true; - } - - uint64_t getCursor() const { return Cursor; } - void advanceCursor(uint32_t n) { Cursor += n * 4; } - -private: - MemoryBuffer *Buffer; - uint64_t Cursor = 0; -}; - -/// GCOVFile - Collects coverage information for one pair of coverage file -/// (.gcno and .gcda). -class GCOVFile { -public: - GCOVFile() = default; - - bool readGCNO(GCOVBuffer &Buffer); - bool readGCDA(GCOVBuffer &Buffer); - uint32_t getChecksum() const { return Checksum; } - void print(raw_ostream &OS) const; - void dump() const; - void collectLineCounts(FileInfo &FI); - -private: - bool GCNOInitialized = false; - GCOV::GCOVVersion Version; - uint32_t Checksum = 0; - SmallVector, 16> Functions; - uint32_t RunCount = 0; - uint32_t ProgramCount = 0; -}; - -/// GCOVEdge - Collects edge information. -struct GCOVEdge { - GCOVEdge(GCOVBlock &S, GCOVBlock &D) : Src(S), Dst(D) {} - - GCOVBlock &Src; - GCOVBlock &Dst; - uint64_t Count = 0; -}; - -/// GCOVFunction - Collects function information. -class GCOVFunction { -public: - using BlockIterator = pointee_iterator>::const_iterator>; - - GCOVFunction(GCOVFile &P) : Parent(P) {} - - bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version); - bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version); - StringRef getName() const { return Name; } - StringRef getFilename() const { return Filename; } - size_t getNumBlocks() const { return Blocks.size(); } - uint64_t getEntryCount() const; - uint64_t getExitCount() const; - - BlockIterator block_begin() const { return Blocks.begin(); } - BlockIterator block_end() const { return Blocks.end(); } - iterator_range blocks() const { - return make_range(block_begin(), block_end()); - } - - void print(raw_ostream &OS) const; - void dump() const; - void collectLineCounts(FileInfo &FI); - -private: - GCOVFile &Parent; - uint32_t Ident = 0; - uint32_t Checksum; - uint32_t LineNumber = 0; - StringRef Name; - StringRef Filename; - SmallVector, 16> Blocks; - SmallVector, 16> Edges; -}; - -/// GCOVBlock - Collects block information. -class GCOVBlock { - struct EdgeWeight { - EdgeWeight(GCOVBlock *D) : Dst(D) {} - - GCOVBlock *Dst; - uint64_t Count = 0; - }; - - struct SortDstEdgesFunctor { - bool operator()(const GCOVEdge *E1, const GCOVEdge *E2) { - return E1->Dst.Number < E2->Dst.Number; - } - }; - -public: - using EdgeIterator = SmallVectorImpl::const_iterator; - - GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N) {} - ~GCOVBlock(); - - const GCOVFunction &getParent() const { return Parent; } - void addLine(uint32_t N) { Lines.push_back(N); } - uint32_t getLastLine() const { return Lines.back(); } - void addCount(size_t DstEdgeNo, uint64_t N); - uint64_t getCount() const { return Counter; } - - void addSrcEdge(GCOVEdge *Edge) { - assert(&Edge->Dst == this); // up to caller to ensure edge is valid - SrcEdges.push_back(Edge); - } - - void addDstEdge(GCOVEdge *Edge) { - assert(&Edge->Src == this); // up to caller to ensure edge is valid - // Check if adding this edge causes list to become unsorted. - if (DstEdges.size() && DstEdges.back()->Dst.Number > Edge->Dst.Number) - DstEdgesAreSorted = false; - DstEdges.push_back(Edge); - } - - size_t getNumSrcEdges() const { return SrcEdges.size(); } - size_t getNumDstEdges() const { return DstEdges.size(); } - void sortDstEdges(); - - EdgeIterator src_begin() const { return SrcEdges.begin(); } - EdgeIterator src_end() const { return SrcEdges.end(); } - iterator_range srcs() const { - return make_range(src_begin(), src_end()); - } - - EdgeIterator dst_begin() const { return DstEdges.begin(); } - EdgeIterator dst_end() const { return DstEdges.end(); } - iterator_range dsts() const { - return make_range(dst_begin(), dst_end()); - } - - void print(raw_ostream &OS) const; - void dump() const; - void collectLineCounts(FileInfo &FI); - -private: - GCOVFunction &Parent; - uint32_t Number; - uint64_t Counter = 0; - bool DstEdgesAreSorted = true; - SmallVector SrcEdges; - SmallVector DstEdges; - SmallVector Lines; -}; - -class FileInfo { - // It is unlikely--but possible--for multiple functions to be on the same - // line. - // Therefore this typedef allows LineData.Functions to store multiple - // functions - // per instance. This is rare, however, so optimize for the common case. - using FunctionVector = SmallVector; - using FunctionLines = DenseMap; - using BlockVector = SmallVector; - using BlockLines = DenseMap; - - struct LineData { - LineData() = default; - - BlockLines Blocks; - FunctionLines Functions; - uint32_t LastLine = 0; - }; - - struct GCOVCoverage { - GCOVCoverage(StringRef Name) : Name(Name) {} - - StringRef Name; - - uint32_t LogicalLines = 0; - uint32_t LinesExec = 0; - - uint32_t Branches = 0; - uint32_t BranchesExec = 0; - uint32_t BranchesTaken = 0; - }; - -public: - FileInfo(const GCOV::Options &Options) : Options(Options) {} - - void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) { - if (Line > LineInfo[Filename].LastLine) - LineInfo[Filename].LastLine = Line; - LineInfo[Filename].Blocks[Line - 1].push_back(Block); - } - - void addFunctionLine(StringRef Filename, uint32_t Line, - const GCOVFunction *Function) { - if (Line > LineInfo[Filename].LastLine) - LineInfo[Filename].LastLine = Line; - LineInfo[Filename].Functions[Line - 1].push_back(Function); - } - - void setRunCount(uint32_t Runs) { RunCount = Runs; } - void setProgramCount(uint32_t Programs) { ProgramCount = Programs; } - void print(raw_ostream &OS, StringRef MainFilename, StringRef GCNOFile, - StringRef GCDAFile); - -private: - std::string getCoveragePath(StringRef Filename, StringRef MainFilename); - std::unique_ptr openCoveragePath(StringRef CoveragePath); - void printFunctionSummary(raw_ostream &OS, const FunctionVector &Funcs) const; - void printBlockInfo(raw_ostream &OS, const GCOVBlock &Block, - uint32_t LineIndex, uint32_t &BlockNo) const; - void printBranchInfo(raw_ostream &OS, const GCOVBlock &Block, - GCOVCoverage &Coverage, uint32_t &EdgeNo); - void printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo, - uint64_t Count) const; - - void printCoverage(raw_ostream &OS, const GCOVCoverage &Coverage) const; - void printFuncCoverage(raw_ostream &OS) const; - void printFileCoverage(raw_ostream &OS) const; - - const GCOV::Options &Options; - StringMap LineInfo; - uint32_t RunCount = 0; - uint32_t ProgramCount = 0; - - using FileCoverageList = SmallVector, 4>; - using FuncCoverageMap = MapVector; - - FileCoverageList FileCoverages; - FuncCoverageMap FuncCoverages; -}; - -} // end namespace llvm - -#endif // LLVM_SUPPORT_GCOV_H From 334d3fb2969275dad485a60175ee73f74541c4e8 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 17 Oct 2021 12:25:13 +0200 Subject: [PATCH 20/37] adapt to SCC changes --- gen_input/templates/interp/CORENAME.cpp.gtl | 5 ++++- incl/iss/arch/riscv_hart_mu_p.h | 2 +- src/vm/interp/vm_tgc_c.cpp | 18 ++++++++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index e3654d6..53cffed 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -92,7 +92,10 @@ protected: // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 }; enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 }; enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 }; - enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) }; + enum { + LUT_SIZE = 1 << util::bit_count(static_cast(EXTR_MASK32)), + LUT_SIZE_C = 1 << util::bit_count(static_cast(EXTR_MASK16)) + }; std::array lut; diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index b6ea430..86bd720 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -493,7 +493,7 @@ template std::pair riscv_hart_m traits::MEM, pseg->get_physical_address(), fsize, reinterpret_cast(seg_data)); if (res != iss::Ok) - LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex + LOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex << pseg->get_physical_address(); } } diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 1cbb859..f515edd 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -30,21 +30,23 @@ * *******************************************************************************/ -// clang-format off +#include "../fp_functions.h" +#include +#include #include #include #include -#include -#include #include -#include "../fp_functions.h" #include #include + +#ifndef FMT_HEADER_ONLY +#define FMT_HEADER_ONLY +#endif #include #include #include -// clang-format on namespace iss { namespace interp { @@ -90,7 +92,10 @@ protected: // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 }; enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 }; enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 }; - enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) }; + enum { + LUT_SIZE = 1 << util::bit_count(static_cast(EXTR_MASK32)), + LUT_SIZE_C = 1 << util::bit_count(static_cast(EXTR_MASK16)) + }; std::array lut; @@ -4098,6 +4103,7 @@ private: return pc; } + //static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK; iss::status fetch_ins(virt_addr_t pc, uint8_t * data){ auto phys_pc = this->core.v2p(pc); //if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary From a20f39e847aad90fbdf71edcbb9145708b26a173 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 30 Oct 2021 12:56:31 +0200 Subject: [PATCH 21/37] update core definitions to include Zicsr and Zifencei (#276) --- gen_input/CoreDSL-Instruction-Set-Description | 2 +- gen_input/TGC_B.core_desc | 2 +- gen_input/TGC_C.core_desc | 2 +- gen_input/TGC_D.core_desc | 2 +- gen_input/TGC_D_XRB_MAC.core_desc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description index 9e3119a..e7aaec6 160000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ b/gen_input/CoreDSL-Instruction-Set-Description @@ -1 +1 @@ -Subproject commit 9e3119a8064e8515eeca7e5298f88d0d9d224458 +Subproject commit e7aaec6ad9336bd83b4da63dd0c96f8d11887661 diff --git a/gen_input/TGC_B.core_desc b/gen_input/TGC_B.core_desc index 78e86ec..3686002 100644 --- a/gen_input/TGC_B.core_desc +++ b/gen_input/TGC_B.core_desc @@ -2,7 +2,7 @@ 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 { +Core TGC_B provides RV32I, Zicsr, Zifencei { architectural_state { XLEN=32; // definitions for the architecture wrapper diff --git a/gen_input/TGC_C.core_desc b/gen_input/TGC_C.core_desc index a8fed39..d3a529e 100644 --- a/gen_input/TGC_C.core_desc +++ b/gen_input/TGC_C.core_desc @@ -2,7 +2,7 @@ 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 { +Core TGC_C provides RV32I, Zicsr, Zifencei, RV32M, RV32IC { architectural_state { XLEN=32; // definitions for the architecture wrapper diff --git a/gen_input/TGC_D.core_desc b/gen_input/TGC_D.core_desc index 9616296..1187485 100644 --- a/gen_input/TGC_D.core_desc +++ b/gen_input/TGC_D.core_desc @@ -2,7 +2,7 @@ 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 { +Core TGC_D provides RV32I, Zicsr, Zifencei, RV32M, RV32IC { architectural_state { XLEN=32; // definitions for the architecture wrapper diff --git a/gen_input/TGC_D_XRB_MAC.core_desc b/gen_input/TGC_D_XRB_MAC.core_desc index 9968d56..972b111 100644 --- a/gen_input/TGC_D_XRB_MAC.core_desc +++ b/gen_input/TGC_D_XRB_MAC.core_desc @@ -62,7 +62,7 @@ InstructionSet X_RB_MAC extends RISCVBase { } } -Core TGC_D_XRB_MAC provides RV32I, RV32M, RV32IC, X_RB_MAC { +Core TGC_D_XRB_MAC provides RV32I, Zicsr, Zifencei, RV32M, RV32IC, X_RB_MAC { architectural_state { XLEN=32; // definitions for the architecture wrapper From 1616f0ac9049e1acc1b434fef9e25e34374ef6b4 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 30 Oct 2021 12:57:08 +0200 Subject: [PATCH 22/37] remove deprecated functions --- gen_input/templates/CORENAME.cpp.gtl | 4 +- gen_input/templates/CORENAME.h.gtl | 8 - incl/iss/arch/tgc_c.h | 85 +++-- src/iss/tgc_c.cpp | 4 +- src/vm/interp/vm_tgc_c.cpp | 454 +++++++++++++++------------ 5 files changed, 293 insertions(+), 262 deletions(-) diff --git a/gen_input/templates/CORENAME.cpp.gtl b/gen_input/templates/CORENAME.cpp.gtl index 9729bc2..849e965 100644 --- a/gen_input/templates/CORENAME.cpp.gtl +++ b/gen_input/templates/CORENAME.cpp.gtl @@ -58,7 +58,9 @@ ${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { ${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default; void ${coreDef.name.toLowerCase()}::reset(uint64_t address) { - for(size_t i=0; i::NUM_REGS; ++i) set_reg(i, std::vector(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0)); + auto base_ptr = reinterpret_cast::reg_t*>(get_regs_base_ptr()); + for(size_t i=0; i::NUM_REGS; ++i) + *(base_ptr+i)=0; reg.PC=address; reg.NEXT_PC=reg.PC; reg.PRIV=0x3; diff --git a/gen_input/templates/CORENAME.h.gtl b/gen_input/templates/CORENAME.h.gtl index 4358777..2105569 100644 --- a/gen_input/templates/CORENAME.h.gtl +++ b/gen_input/templates/CORENAME.h.gtl @@ -140,14 +140,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { void reset(uint64_t address=0) override; uint8_t* get_regs_base_ptr() override; - /// deprecated - void get_reg(short idx, std::vector& value) override {} - void set_reg(short idx, const std::vector& value) override {} - /// deprecated - bool get_flag(int flag) override {return false;} - void set_flag(int, bool value) override {}; - /// deprecated - void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; inline uint64_t get_icount() { return reg.icount; } diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index 5a96c9e..e7e440a 100644 --- a/incl/iss/arch/tgc_c.h +++ b/incl/iss/arch/tgc_c.h @@ -139,44 +139,45 @@ template <> struct traits { CSRRWI = 47, CSRRSI = 48, CSRRCI = 49, - MUL = 50, - MULH = 51, - MULHSU = 52, - MULHU = 53, - DIV = 54, - DIVU = 55, - REM = 56, - REMU = 57, - CADDI4SPN = 58, - CLW = 59, - CSW = 60, - CADDI = 61, - CNOP = 62, - CJAL = 63, - CLI = 64, - CLUI = 65, - CADDI16SP = 66, - __reserved_clui = 67, - CSRLI = 68, - CSRAI = 69, - CANDI = 70, - CSUB = 71, - CXOR = 72, - COR = 73, - CAND = 74, - CJ = 75, - CBEQZ = 76, - CBNEZ = 77, - CSLLI = 78, - CLWSP = 79, - CMV = 80, - CJR = 81, - __reserved_cmv = 82, - CADD = 83, - CJALR = 84, - CEBREAK = 85, - CSWSP = 86, - DII = 87, + FENCE_I = 50, + MUL = 51, + MULH = 52, + MULHSU = 53, + MULHU = 54, + DIV = 55, + DIVU = 56, + REM = 57, + REMU = 58, + CADDI4SPN = 59, + CLW = 60, + CSW = 61, + CADDI = 62, + CNOP = 63, + CJAL = 64, + CLI = 65, + CLUI = 66, + CADDI16SP = 67, + __reserved_clui = 68, + CSRLI = 69, + CSRAI = 70, + CANDI = 71, + CSUB = 72, + CXOR = 73, + COR = 74, + CAND = 75, + CJ = 76, + CBEQZ = 77, + CBNEZ = 78, + CSLLI = 79, + CLWSP = 80, + CMV = 81, + CJR = 82, + __reserved_cmv = 83, + CADD = 84, + CJALR = 85, + CEBREAK = 86, + CSWSP = 87, + DII = 88, MAX_OPCODE }; }; @@ -194,14 +195,6 @@ struct tgc_c: public arch_if { void reset(uint64_t address=0) override; uint8_t* get_regs_base_ptr() override; - /// deprecated - void get_reg(short idx, std::vector& value) override {} - void set_reg(short idx, const std::vector& value) override {} - /// deprecated - bool get_flag(int flag) override {return false;} - void set_flag(int, bool value) override {}; - /// deprecated - void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; inline uint64_t get_icount() { return reg.icount; } diff --git a/src/iss/tgc_c.cpp b/src/iss/tgc_c.cpp index 31ac7b7..1dd9e89 100644 --- a/src/iss/tgc_c.cpp +++ b/src/iss/tgc_c.cpp @@ -51,7 +51,9 @@ tgc_c::tgc_c() { tgc_c::~tgc_c() = default; void tgc_c::reset(uint64_t address) { - for(size_t i=0; i::NUM_REGS; ++i) set_reg(i, std::vector(sizeof(traits::reg_t),0)); + auto base_ptr = reinterpret_cast::reg_t*>(get_regs_base_ptr()); + for(size_t i=0; i::NUM_REGS; ++i) + *(base_ptr+i)=0; reg.PC=address; reg.NEXT_PC=reg.PC; reg.PRIV=0x3; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index f515edd..7bbcf36 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -180,7 +180,7 @@ private: compile_func op; }; - const std::array instr_descr = {{ + const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */ /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, @@ -282,6 +282,8 @@ private: {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, /* instruction CSRRCI */ {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, + /* instruction FENCE_I */ + {32, 0b00000000000000000001000000001111, 0b00000000000000000111000001111111, &this_class::__fence_i}, /* instruction MUL */ {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, /* instruction MULH */ @@ -2485,8 +2487,8 @@ private: return pc; } - /* instruction 50: MUL */ - compile_ret_t __mul(virt_addr_t& pc, code_word_t instr){ + /* instruction 50: FENCE_I */ + compile_ret_t __fence_i(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -2496,6 +2498,46 @@ private: if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 50); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + 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); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + writeSpace2(traits::FENCE, traits::fencei, imm); + } catch(...){} + // post execution stuff + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); + // trap check + if(*trap_state!=0){ + super::core.enter_trap(*trap_state, pc.val, instr); + } else { + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; + return pc; + } + + /* instruction 51: MUL */ + compile_ret_t __mul(virt_addr_t& pc, code_word_t instr){ + // pre execution stuff + auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *PC=*NEXT_PC; + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 51); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2518,7 +2560,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2531,7 +2573,7 @@ private: return pc; } - /* instruction 51: MULH */ + /* instruction 52: MULH */ compile_ret_t __mulh(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2539,7 +2581,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 51); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 52); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2564,7 +2606,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2577,7 +2619,7 @@ private: return pc; } - /* instruction 52: MULHSU */ + /* instruction 53: MULHSU */ compile_ret_t __mulhsu(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2585,7 +2627,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 52); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 53); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2610,7 +2652,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2623,7 +2665,7 @@ private: return pc; } - /* instruction 53: MULHU */ + /* instruction 54: MULHU */ compile_ret_t __mulhu(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2631,7 +2673,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 53); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 54); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2656,7 +2698,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2669,7 +2711,7 @@ private: return pc; } - /* instruction 54: DIV */ + /* instruction 55: DIV */ compile_ret_t __div(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2677,7 +2719,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 54); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 55); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2706,7 +2748,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2719,7 +2761,7 @@ private: return pc; } - /* instruction 55: DIVU */ + /* instruction 56: DIVU */ compile_ret_t __divu(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2727,7 +2769,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 55); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 56); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2752,7 +2794,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2765,7 +2807,7 @@ private: return pc; } - /* instruction 56: REM */ + /* instruction 57: REM */ compile_ret_t __rem(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2773,7 +2815,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 56); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 57); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2802,7 +2844,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2815,7 +2857,7 @@ private: return pc; } - /* instruction 57: REMU */ + /* instruction 58: REMU */ compile_ret_t __remu(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2823,7 +2865,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 57); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 58); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2848,7 +2890,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2861,7 +2903,7 @@ private: return pc; } - /* instruction 58: CADDI4SPN */ + /* instruction 59: CADDI4SPN */ compile_ret_t __caddi4spn(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2869,7 +2911,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 58); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 59); uint8_t rd = ((bit_sub<2,3>(instr))); uint16_t imm = ((bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4)); if(this->disass_enabled){ @@ -2889,7 +2931,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2902,7 +2944,7 @@ private: return pc; } - /* instruction 59: CLW */ + /* instruction 60: CLW */ compile_ret_t __clw(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2910,7 +2952,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 59); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 60); uint8_t rd = ((bit_sub<2,3>(instr))); uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -2933,7 +2975,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2946,7 +2988,7 @@ private: return pc; } - /* instruction 60: CSW */ + /* instruction 61: CSW */ compile_ret_t __csw(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2954,7 +2996,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 60); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 61); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -2977,7 +3019,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2990,7 +3032,7 @@ private: return pc; } - /* instruction 61: CADDI */ + /* instruction 62: CADDI */ compile_ret_t __caddi(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2998,7 +3040,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 61); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 62); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3017,7 +3059,7 @@ private: *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3030,7 +3072,7 @@ private: return pc; } - /* instruction 62: CNOP */ + /* instruction 63: CNOP */ compile_ret_t __cnop(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3038,7 +3080,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 62); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 63); uint8_t nzimm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3053,7 +3095,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3066,7 +3108,7 @@ private: return pc; } - /* instruction 63: CJAL */ + /* instruction 64: CJAL */ compile_ret_t __cjal(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3074,7 +3116,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 63); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 64); uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3095,7 +3137,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3108,7 +3150,7 @@ private: return pc; } - /* instruction 64: CLI */ + /* instruction 65: CLI */ compile_ret_t __cli(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3116,7 +3158,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 64); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 65); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3137,7 +3179,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3150,7 +3192,7 @@ private: return pc; } - /* instruction 65: CLUI */ + /* instruction 66: CLUI */ compile_ret_t __clui(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3158,7 +3200,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 65); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 66); uint32_t imm = ((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3180,7 +3222,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3193,7 +3235,7 @@ private: return pc; } - /* instruction 66: CADDI16SP */ + /* instruction 67: CADDI16SP */ compile_ret_t __caddi16sp(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3201,7 +3243,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 66); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 67); uint16_t nzimm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3220,41 +3262,6 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); - // trap check - if(*trap_state!=0){ - super::core.enter_trap(*trap_state, pc.val, instr); - } else { - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; - } - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; - pc.val=*NEXT_PC; - return pc; - } - - /* instruction 67: __reserved_clui */ - compile_ret_t ____reserved_clui(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); - auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - *PC=*NEXT_PC; - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 67); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "__reserved_clui"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - } catch(...){} - // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); // trap check if(*trap_state!=0){ @@ -3268,8 +3275,8 @@ private: return pc; } - /* instruction 68: CSRLI */ - compile_ret_t __csrli(virt_addr_t& pc, code_word_t instr){ + /* instruction 68: __reserved_clui */ + compile_ret_t ____reserved_clui(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -3277,6 +3284,41 @@ private: auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 68); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "__reserved_clui"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + raise(0, 2); + } catch(...){} + // post execution stuff + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); + // trap check + if(*trap_state!=0){ + super::core.enter_trap(*trap_state, pc.val, instr); + } else { + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; + return pc; + } + + /* instruction 69: CSRLI */ + compile_ret_t __csrli(virt_addr_t& pc, code_word_t instr){ + // pre execution stuff + auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *PC=*NEXT_PC; + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 69); uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3298,7 +3340,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3311,7 +3353,7 @@ private: return pc; } - /* instruction 69: CSRAI */ + /* instruction 70: CSRAI */ compile_ret_t __csrai(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3319,7 +3361,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 69); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 70); uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3345,7 +3387,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3358,7 +3400,7 @@ private: return pc; } - /* instruction 70: CANDI */ + /* instruction 71: CANDI */ compile_ret_t __candi(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3366,7 +3408,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 70); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 71); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3388,7 +3430,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3401,7 +3443,7 @@ private: return pc; } - /* instruction 71: CSUB */ + /* instruction 72: CSUB */ compile_ret_t __csub(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3409,7 +3451,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 71); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 72); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3431,7 +3473,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3444,7 +3486,7 @@ private: return pc; } - /* instruction 72: CXOR */ + /* instruction 73: CXOR */ compile_ret_t __cxor(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3452,7 +3494,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 72); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 73); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3474,7 +3516,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3487,7 +3529,7 @@ private: return pc; } - /* instruction 73: COR */ + /* instruction 74: COR */ compile_ret_t __cor(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3495,7 +3537,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 73); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 74); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3517,7 +3559,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3530,7 +3572,7 @@ private: return pc; } - /* instruction 74: CAND */ + /* instruction 75: CAND */ compile_ret_t __cand(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3538,7 +3580,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 74); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 75); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3560,7 +3602,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3573,7 +3615,7 @@ private: return pc; } - /* instruction 75: CJ */ + /* instruction 76: CJ */ compile_ret_t __cj(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3581,7 +3623,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 75); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 76); uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3598,7 +3640,7 @@ private: pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3611,7 +3653,7 @@ private: return pc; } - /* instruction 76: CBEQZ */ + /* instruction 77: CBEQZ */ compile_ret_t __cbeqz(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3619,7 +3661,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 76); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 77); uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3638,7 +3680,7 @@ private: if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3651,7 +3693,7 @@ private: return pc; } - /* instruction 77: CBNEZ */ + /* instruction 78: CBNEZ */ compile_ret_t __cbnez(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3659,7 +3701,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 77); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 78); uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3678,7 +3720,7 @@ private: if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3691,7 +3733,7 @@ private: return pc; } - /* instruction 78: CSLLI */ + /* instruction 79: CSLLI */ compile_ret_t __cslli(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3699,7 +3741,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 78); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 79); uint8_t nzuimm = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3718,7 +3760,7 @@ private: if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3731,7 +3773,7 @@ private: return pc; } - /* instruction 79: CLWSP */ + /* instruction 80: CLWSP */ compile_ret_t __clwsp(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3739,7 +3781,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 79); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 80); uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3762,7 +3804,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3775,7 +3817,7 @@ private: return pc; } - /* instruction 80: CMV */ + /* instruction 81: CMV */ compile_ret_t __cmv(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3783,7 +3825,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 80); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 81); uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3802,7 +3844,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3815,7 +3857,7 @@ private: return pc; } - /* instruction 81: CJR */ + /* instruction 82: CJR */ compile_ret_t __cjr(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3823,7 +3865,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 81); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 82); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3842,40 +3884,6 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); - // trap check - if(*trap_state!=0){ - super::core.enter_trap(*trap_state, pc.val, instr); - } else { - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; - } - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; - pc.val=*NEXT_PC; - return pc; - } - - /* instruction 82: __reserved_cmv */ - compile_ret_t ____reserved_cmv(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); - auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - *PC=*NEXT_PC; - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 82); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "__reserved_cmv"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - } catch(...){} - // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); // trap check if(*trap_state!=0){ @@ -3889,8 +3897,8 @@ private: return pc; } - /* instruction 83: CADD */ - compile_ret_t __cadd(virt_addr_t& pc, code_word_t instr){ + /* instruction 83: __reserved_cmv */ + compile_ret_t ____reserved_cmv(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -3898,6 +3906,40 @@ private: auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 83); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "__reserved_cmv"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + raise(0, 2); + } catch(...){} + // post execution stuff + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); + // trap check + if(*trap_state!=0){ + super::core.enter_trap(*trap_state, pc.val, instr); + } else { + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; + return pc; + } + + /* instruction 84: CADD */ + compile_ret_t __cadd(virt_addr_t& pc, code_word_t instr){ + // pre execution stuff + auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *PC=*NEXT_PC; + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 84); uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3916,7 +3958,7 @@ private: if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3929,7 +3971,7 @@ private: return pc; } - /* instruction 84: CJALR */ + /* instruction 85: CJALR */ compile_ret_t __cjalr(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3937,7 +3979,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 84); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 85); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3959,40 +4001,6 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); - // trap check - if(*trap_state!=0){ - super::core.enter_trap(*trap_state, pc.val, instr); - } else { - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; - } - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; - pc.val=*NEXT_PC; - return pc; - } - - /* instruction 85: CEBREAK */ - compile_ret_t __cebreak(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); - auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - *PC=*NEXT_PC; - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 85); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "cebreak"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 3); - } catch(...){} - // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); // trap check if(*trap_state!=0){ @@ -4006,8 +4014,8 @@ private: return pc; } - /* instruction 86: CSWSP */ - compile_ret_t __cswsp(virt_addr_t& pc, code_word_t instr){ + /* instruction 86: CEBREAK */ + compile_ret_t __cebreak(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -4015,6 +4023,40 @@ private: auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 86); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "cebreak"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + raise(0, 3); + } catch(...){} + // post execution stuff + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); + // trap check + if(*trap_state!=0){ + super::core.enter_trap(*trap_state, pc.val, instr); + } else { + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; + return pc; + } + + /* instruction 87: CSWSP */ + compile_ret_t __cswsp(virt_addr_t& pc, code_word_t instr){ + // pre execution stuff + auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *PC=*NEXT_PC; + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 87); uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); if(this->disass_enabled){ @@ -4036,7 +4078,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -4049,7 +4091,7 @@ private: return pc; } - /* instruction 87: DII */ + /* instruction 88: DII */ compile_ret_t __dii(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -4057,7 +4099,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 87); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 88); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "dii"); @@ -4070,7 +4112,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 88); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); From 8b6e3abd234485187ca9941712c4b0c76300145a Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 30 Oct 2021 13:37:17 +0200 Subject: [PATCH 23/37] fix hard-code arch in templates --- gen_input/templates/CORENAME.cpp.gtl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen_input/templates/CORENAME.cpp.gtl b/gen_input/templates/CORENAME.cpp.gtl index 849e965..6bb5c4e 100644 --- a/gen_input/templates/CORENAME.cpp.gtl +++ b/gen_input/templates/CORENAME.cpp.gtl @@ -59,7 +59,7 @@ ${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default; void ${coreDef.name.toLowerCase()}::reset(uint64_t address) { auto base_ptr = reinterpret_cast::reg_t*>(get_regs_base_ptr()); - for(size_t i=0; i::NUM_REGS; ++i) + for(size_t i=0; i::NUM_REGS; ++i) *(base_ptr+i)=0; reg.PC=address; reg.NEXT_PC=reg.PC; From ff04ee780761d97518d1596fdd94333f0aa2f738 Mon Sep 17 00:00:00 2001 From: Stas Date: Tue, 2 Nov 2021 10:24:34 +0100 Subject: [PATCH 24/37] get rid of the Boost::thread linking --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a7e14c..7577443 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,9 +114,9 @@ endif() # Links the target exe against the libraries target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc) if(TARGET Boost::program_options) - target_link_libraries(${PROJECT_NAME} PUBLIC Boost::program_options Boost::thread) + target_link_libraries(${PROJECT_NAME} PUBLIC Boost::program_options) else() - target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY} ${BOOST_thread_LIBRARY}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY}) endif() target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_DL_LIBS}) if (Tcmalloc_FOUND) From a89f00da19a3eafbd0ba83bff0cbbf91b1c6d5f9 Mon Sep 17 00:00:00 2001 From: Stas Date: Tue, 2 Nov 2021 11:03:17 +0100 Subject: [PATCH 25/37] fix plugins parameter utilization --- src/sysc/core_complex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index fbe30e2..171eaaa 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -397,7 +397,7 @@ void core_complex::before_end_of_elaboration() { cpu->create_cpu(GET_PROP_VALUE(core_type), GET_PROP_VALUE(backend), GET_PROP_VALUE(gdb_server_port), GET_PROP_VALUE(mhartid)); sc_assert(cpu->vm!=nullptr); cpu->vm->setDisassEnabled(GET_PROP_VALUE(enable_disass) || trc->m_db != nullptr); - if (GET_PROP_VALUE(core_type).length()) { + if (GET_PROP_VALUE(plugins).length()) { auto p = util::split(GET_PROP_VALUE(plugins), ';'); for (std::string const& opt_val : p) { std::string plugin_name=opt_val; From ac6d7ea5d4e15c7cc18187271b2cd2f59b0f0144 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 2 Nov 2021 11:13:29 +0100 Subject: [PATCH 26/37] add debug feature to platform --- incl/iss/arch/riscv_hart_common.h | 5 +- incl/iss/arch/riscv_hart_m_p.h | 147 +++++++++++++++++++----------- incl/iss/arch/riscv_hart_mu_p.h | 21 ++++- 3 files changed, 119 insertions(+), 54 deletions(-) diff --git a/incl/iss/arch/riscv_hart_common.h b/incl/iss/arch/riscv_hart_common.h index 7cd6f72..ffe87bc 100644 --- a/incl/iss/arch/riscv_hart_common.h +++ b/incl/iss/arch/riscv_hart_common.h @@ -43,6 +43,8 @@ namespace arch { enum { tohost_dflt = 0xF0001000, fromhost_dflt = 0xF0001040 }; +enum features_e{FEAT_NONE, FEAT_PMP=1, FEAT_EXT_N=2, FEAT_CLIC=4, FEAT_DEBUG=8}; + enum riscv_csr { /* user-level CSR */ // User Trap Setup @@ -164,7 +166,8 @@ enum riscv_csr { // Debug Mode Registers dcsr = 0x7B0, dpc = 0x7B1, - dscratch = 0x7B2 + dscratch0 = 0x7B2, + dscratch1 = 0x7B3 }; diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index b76f14d..fa7324a 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -66,7 +66,7 @@ namespace iss { namespace arch { -template class riscv_hart_m_p : public BASE { +template class riscv_hart_m_p : public BASE { protected: const std::array lvl = {{'U', 'S', 'H', 'M'}}; const std::array trap_str = {{"" @@ -92,7 +92,7 @@ protected: "User external interrupt", "Supervisor external interrupt", "Reserved", "Machine external interrupt"}}; public: using core = BASE; - using this_class = riscv_hart_m_p; + using this_class = riscv_hart_m_p; using phys_addr_t = typename core::phys_addr_t; using reg_t = typename core::reg_t; using addr_t = typename core::addr_t; @@ -221,7 +221,7 @@ public: protected: struct riscv_instrumentation_if : public iss::instrumentation_if { - riscv_instrumentation_if(riscv_hart_m_p &arch) + riscv_instrumentation_if(riscv_hart_m_p &arch) : arch(arch) {} /** * get the name of this architecture @@ -236,7 +236,7 @@ protected: virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; }; - riscv_hart_m_p &arch; + riscv_hart_m_p &arch; }; friend struct riscv_instrumentation_if; @@ -246,6 +246,9 @@ protected: 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); + iss::status read_clic(uint64_t addr, unsigned length, uint8_t *const data); + iss::status write_clic(uint64_t addr, unsigned length, const uint8_t *const data); + virtual iss::status read_csr(unsigned addr, reg_t &val); virtual iss::status write_csr(unsigned addr, reg_t val); @@ -270,10 +273,23 @@ protected: std::unordered_map atomic_reservation; std::unordered_map csr_rd_cb; std::unordered_map csr_wr_cb; + uint8_t clic_cfg_reg{0}; + uint32_t clic_info_reg{0}; + std::array clic_inttrig_reg; + union clic_int_reg_t { + struct{ + uint8_t ip; + uint8_t ie; + uint8_t attr; + uint8_t ctl; + }; + uint32_t raw; + }; + std::vector clic_int_reg; private: - iss::status read_reg(unsigned addr, reg_t &val); - iss::status write_reg(unsigned addr, reg_t val); + iss::status read_csr_reg(unsigned addr, reg_t &val); + iss::status write_csr_reg(unsigned addr, reg_t val); iss::status read_null(unsigned addr, reg_t &val); iss::status write_null(unsigned addr, reg_t val){return iss::status::Ok;} iss::status read_cycle(unsigned addr, reg_t &val); @@ -291,17 +307,22 @@ private: iss::status write_ip(unsigned addr, reg_t val); iss::status read_hartid(unsigned addr, reg_t &val); iss::status write_epc(unsigned addr, reg_t val); - + iss::status write_dcsr(unsigned addr, reg_t val); reg_t mhartid_reg{0x0}; std::functionmem_read_cb; std::function mem_write_cb; protected: void check_interrupt(); + bool pmp_check(const access_type type, const uint64_t addr, const unsigned len); + uint64_t clic_base_addr{0}; + unsigned clic_num_irq{0}; + unsigned clic_num_trigger{0}; + unsigned mcause_max_irq{16}; }; -template -riscv_hart_m_p::riscv_hart_m_p() +template +riscv_hart_m_p::riscv_hart_m_p() : state() , instr_if(*this) { // reset values @@ -309,32 +330,33 @@ riscv_hart_m_p::riscv_hart_m_p() csr[mvendorid] = 0x669; csr[marchid] = traits::MARCHID_VAL; csr[mimpid] = 1; + csr[mclicbase] = 0xc0000000; // TODO: should be taken from YAML file uart_buf.str(""); for (unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr){ csr_rd_cb[addr] = &this_class::read_null; - csr_wr_cb[addr] = &this_class::write_reg; + csr_wr_cb[addr] = &this_class::write_csr_reg; } for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){ csr_rd_cb[addr] = &this_class::read_null; - csr_wr_cb[addr] = &this_class::write_reg; + csr_wr_cb[addr] = &this_class::write_csr_reg; } for (unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr){ csr_rd_cb[addr] = &this_class::read_null; - csr_wr_cb[addr] = &this_class::write_reg; + csr_wr_cb[addr] = &this_class::write_csr_reg; } for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){ csr_rd_cb[addr] = &this_class::read_null; } for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){ csr_rd_cb[addr] = &this_class::read_null; - //csr_wr_cb[addr] = &this_class::write_reg; + //csr_wr_cb[addr] = &this_class::write_csr_reg; } // common regs const std::array addrs{{misa, mvendorid, marchid, mimpid, mepc, mtvec, mscratch, mcause, mtval, mscratch}}; for(auto addr: addrs) { - csr_rd_cb[addr] = &this_class::read_reg; - csr_wr_cb[addr] = &this_class::write_reg; + csr_rd_cb[addr] = &this_class::read_csr_reg; + csr_wr_cb[addr] = &this_class::write_csr_reg; } // special handling & overrides csr_rd_cb[time] = &this_class::read_time; @@ -362,15 +384,23 @@ riscv_hart_m_p::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_wr_cb[misa] = &this_class::write_null; csr_wr_cb[mvendorid] = &this_class::write_null; csr_wr_cb[marchid] = &this_class::write_null; csr_wr_cb[mimpid] = &this_class::write_null; + if(FEAT & FEAT_DEBUG){ + csr_wr_cb[dscratch0] = &this_class::write_csr_reg; + csr_rd_cb[dscratch0] = &this_class::read_csr_reg; + csr_wr_cb[dscratch1] = &this_class::write_csr_reg; + csr_rd_cb[dscratch1] = &this_class::read_csr_reg; + csr_wr_cb[dpc] = &this_class::write_csr_reg; + csr_rd_cb[dpc] = &this_class::read_csr_reg; + csr_wr_cb[dcsr] = &this_class::write_dcsr; + csr_rd_cb[dcsr] = &this_class::read_csr_reg; + } } -template std::pair riscv_hart_m_p::load_file(std::string name, int type) { +template std::pair riscv_hart_m_p::load_file(std::string name, int type) { FILE *fp = fopen(name.c_str(), "r"); if (fp) { std::array buf; @@ -436,8 +466,8 @@ template std::pair riscv_hart_m_p::load_fi throw std::runtime_error("memory load file not found"); } -template -iss::status riscv_hart_m_p::read(const address_type type, const access_type access, const uint32_t space, +template +iss::status riscv_hart_m_p::read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, const unsigned length, uint8_t *const data) { #ifndef NDEBUG if (access && iss::access_type::DEBUG) { @@ -505,8 +535,8 @@ iss::status riscv_hart_m_p::read(const address_type type, const access_typ } } -template -iss::status riscv_hart_m_p::write(const address_type type, const access_type access, const uint32_t space, +template +iss::status riscv_hart_m_p::write(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, const unsigned length, const uint8_t *const data) { #ifndef NDEBUG const char *prefix = (access && iss::access_type::DEBUG) ? "debug " : ""; @@ -621,7 +651,7 @@ iss::status riscv_hart_m_p::write(const address_type type, const access_ty } } -template iss::status riscv_hart_m_p::read_csr(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_csr(unsigned addr, reg_t &val) { if (addr >= csr.size()) return iss::Err; auto req_priv_lvl = (addr >> 8) & 0x3; if (this->reg.PRIV < req_priv_lvl) // not having required privileges @@ -632,7 +662,7 @@ template iss::status riscv_hart_m_p::read_csr(unsigned add return (this->*(it->second))(addr, val); } -template iss::status riscv_hart_m_p::write_csr(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_csr(unsigned addr, reg_t val) { if (addr >= csr.size()) return iss::Err; auto req_priv_lvl = (addr >> 8) & 0x3; if (this->reg.PRIV < req_priv_lvl) // not having required privileges @@ -645,22 +675,22 @@ template iss::status riscv_hart_m_p::write_csr(unsigned ad return (this->*(it->second))(addr, val); } -template iss::status riscv_hart_m_p::read_reg(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_csr_reg(unsigned addr, reg_t &val) { val = csr[addr]; return iss::Ok; } -template iss::status riscv_hart_m_p::read_null(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_null(unsigned addr, reg_t &val) { val = 0; return iss::Ok; } -template iss::status riscv_hart_m_p::write_reg(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_csr_reg(unsigned addr, reg_t val) { csr[addr] = val; return iss::Ok; } -template iss::status riscv_hart_m_p::read_cycle(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_cycle(unsigned addr, reg_t &val) { auto cycle_val = this->reg.icount + cycle_offset; if (addr == mcycle) { val = static_cast(cycle_val); @@ -671,7 +701,7 @@ template iss::status riscv_hart_m_p::read_cycle(unsigned a return iss::Ok; } -template iss::status riscv_hart_m_p::write_cycle(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_cycle(unsigned addr, reg_t val) { if (sizeof(typename traits::reg_t) != 4) { if (addr == mcycleh) return iss::Err; @@ -687,7 +717,7 @@ template iss::status riscv_hart_m_p::write_cycle(unsigned return iss::Ok; } -template iss::status riscv_hart_m_p::read_instret(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_instret(unsigned addr, reg_t &val) { if ((addr&0xff) == (minstret&0xff)) { val = static_cast(this->reg.instret); } else if ((addr&0xff) == (minstreth&0xff)) { @@ -697,7 +727,7 @@ template iss::status riscv_hart_m_p::read_instret(unsigned return iss::Ok; } -template iss::status riscv_hart_m_p::write_instret(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_instret(unsigned addr, reg_t val) { if (sizeof(typename traits::reg_t) != 4) { if ((addr&0xff) == (minstreth&0xff)) return iss::Err; @@ -713,7 +743,7 @@ template iss::status riscv_hart_m_p::write_instret(unsigne return iss::Ok; } -template iss::status riscv_hart_m_p::read_time(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_time(unsigned addr, reg_t &val) { uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052; if (addr == time) { val = static_cast(time_val); @@ -724,50 +754,50 @@ template iss::status riscv_hart_m_p::read_time(unsigned ad return iss::Ok; } -template iss::status riscv_hart_m_p::read_tvec(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_tvec(unsigned addr, reg_t &val) { val = csr[mtvec] & ~2; return iss::Ok; } -template iss::status riscv_hart_m_p::read_status(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_status(unsigned addr, reg_t &val) { val = state.mstatus & hart_state_type::get_mask(); return iss::Ok; } -template iss::status riscv_hart_m_p::write_status(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_status(unsigned addr, reg_t val) { state.write_mstatus(val); check_interrupt(); return iss::Ok; } -template iss::status riscv_hart_m_p::write_cause(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_cause(unsigned addr, reg_t val) { csr[mcause] = val & ((1UL<<(traits::XLEN-1))|0xf); //TODO: make exception code size configurable return iss::Ok; } -template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t &val) { val = csr[mie]; return iss::Ok; } -template iss::status riscv_hart_m_p::read_hartid(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_hartid(unsigned addr, reg_t &val) { val = mhartid_reg; return iss::Ok; } -template iss::status riscv_hart_m_p::write_ie(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_ie(unsigned addr, reg_t val) { auto mask = get_irq_mask(); csr[mie] = (csr[mie] & ~mask) | (val & mask); check_interrupt(); return iss::Ok; } -template iss::status riscv_hart_m_p::read_ip(unsigned addr, reg_t &val) { +template iss::status riscv_hart_m_p::read_ip(unsigned addr, reg_t &val) { val = csr[mip]; return iss::Ok; } -template iss::status riscv_hart_m_p::write_ip(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_ip(unsigned addr, reg_t val) { auto mask = get_irq_mask(); mask &= ~(1 << 7); // MTIP is read only csr[mip] = (csr[mip] & ~mask) | (val & mask); @@ -775,13 +805,22 @@ template iss::status riscv_hart_m_p::write_ip(unsigned add return iss::Ok; } -template iss::status riscv_hart_m_p::write_epc(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_epc(unsigned addr, reg_t val) { csr[addr] = val & get_pc_mask(); return iss::Ok; } -template -iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { +template iss::status riscv_hart_m_p::write_dcsr(unsigned addr, reg_t val) { + // +-------------- ebreakm + // | +---------- stepi + // | | +++----- cause + // | | ||| +- step + csr[addr] = val & 0b1000100111000100U; + return iss::Ok; +} + +template +iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { if(mem_read_cb) return mem_read_cb(paddr, length, data); switch (paddr.val) { case 0x0200BFF8: { // CLINT base, mtime reg @@ -805,8 +844,8 @@ iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, u return iss::Ok; } -template -iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { +template +iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { if(mem_write_cb) return mem_write_cb(paddr, length, data); switch (paddr.val) { case 0x10013000: // UART0 base, TXFIFO reg @@ -883,12 +922,12 @@ iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned length, return iss::Ok; } -template inline void riscv_hart_m_p::reset(uint64_t address) { +template inline void riscv_hart_m_p::reset(uint64_t address) { BASE::reset(address); state.mstatus = hart_state_type::mstatus_reset_val; } -template void riscv_hart_m_p::check_interrupt() { +template void riscv_hart_m_p::check_interrupt() { //auto ideleg = csr[mideleg]; // Multiple simultaneous interrupts and traps at the same privilege level are // handled in the following decreasing priority order: @@ -910,14 +949,14 @@ template void riscv_hart_m_p::check_interrupt() { } } -template uint64_t riscv_hart_m_p::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) { +template uint64_t riscv_hart_m_p::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) { // flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0] // calculate and write mcause val auto trap_id = bit_sub<0, 16>(flags); auto cause = bit_sub<16, 15>(flags); - if (trap_id == 0 && cause == 11) cause = 0x8 + PRIV_M; // adjust environment call cause // calculate effective privilege level if (trap_id == 0) { // exception + if (cause == 11) cause = 0x8 + PRIV_M; // adjust environment call cause // store ret addr in xepc register csr[mepc] = static_cast(addr) & get_pc_mask(); // store actual address instruction of exception switch(cause){ @@ -927,6 +966,12 @@ template uint64_t riscv_hart_m_p::enter_trap(uint64_t flag case 2: csr[mtval] = (instr & 0x3)==3?instr:instr&0xffff; break; + case 3: + //TODO: implement debug mode behavior + // csr[dpc] = addr; + // csr[dcsr] = (csr[dcsr] & ~0x1c3) | (1<<6) | PRIV_M; //FIXME: cause should not be 4 (stepi) + csr[mtval] = addr; + break; default: csr[mtval] = fault_data; } @@ -969,7 +1014,7 @@ template uint64_t riscv_hart_m_p::enter_trap(uint64_t flag return this->reg.NEXT_PC; } -template uint64_t riscv_hart_m_p::leave_trap(uint64_t flags) { +template uint64_t riscv_hart_m_p::leave_trap(uint64_t flags) { state.mstatus.MIE = state.mstatus.MPIE; state.mstatus.MPIE = 1; // sets the pc to the value stored in the x epc register. diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 86bd720..bb25f2e 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -66,8 +66,6 @@ namespace iss { namespace arch { -enum features_e{FEAT_NONE, FEAT_PMP, FEAT_EXT_N, FEAT_CLIC}; - template class riscv_hart_mu_p : public BASE { protected: const std::array lvl = {{'U', 'S', 'H', 'M'}}; @@ -326,6 +324,7 @@ private: iss::status write_edeleg(unsigned addr, reg_t val); iss::status read_hartid(unsigned addr, reg_t &val); iss::status write_epc(unsigned addr, reg_t val); + iss::status write_dcsr(unsigned addr, reg_t val); iss::status write_intstatus(unsigned addr, reg_t val); iss::status write_intthresh(unsigned addr, reg_t val); @@ -464,6 +463,16 @@ riscv_hart_mu_p::riscv_hart_mu_p() clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + clic_num_irq; mcause_max_irq=clic_num_irq+16; } + if(FEAT & FEAT_DEBUG){ + csr_wr_cb[dscratch0] = &this_class::write_csr_reg; + csr_rd_cb[dscratch0] = &this_class::read_csr_reg; + csr_wr_cb[dscratch1] = &this_class::write_csr_reg; + csr_rd_cb[dscratch1] = &this_class::read_csr_reg; + csr_wr_cb[dpc] = &this_class::write_csr_reg; + csr_rd_cb[dpc] = &this_class::read_csr_reg; + csr_wr_cb[dcsr] = &this_class::write_dcsr; + csr_rd_cb[dcsr] = &this_class::read_csr_reg; + } } template std::pair riscv_hart_mu_p::load_file(std::string name, int type) { @@ -968,6 +977,14 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_dcsr(unsigned addr, reg_t val) { + // +-------------- ebreakm + // | +---------- stepi + // | | +++----- cause + // | | ||| +- step + csr[addr] = val & 0b1000100111000100U; + return iss::Ok; +} template iss::status riscv_hart_mu_p::write_intthresh(unsigned addr, reg_t val) { csr[addr]= val &0xff; From 039746112bcfb7e447fe09091501a3a454220b6a Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 2 Nov 2021 15:10:20 +0100 Subject: [PATCH 27/37] fix exception behavior --- incl/iss/arch/riscv_hart_m_p.h | 17 ++++++++++++++--- incl/iss/arch/riscv_hart_mu_p.h | 21 ++++++++++++++++++++- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index fa7324a..9133285 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -959,9 +959,16 @@ template uint64_t riscv_hart_m_p::e if (cause == 11) cause = 0x8 + PRIV_M; // adjust environment call cause // store ret addr in xepc register csr[mepc] = static_cast(addr) & get_pc_mask(); // store actual address instruction of exception + /* + * write mtval if new_priv=M_MODE, spec says: + * When a hardware breakpoint is triggered, or an instruction-fetch, load, + * or store address-misaligned, + * access, or page-fault exception occurs, mtval is written with the + * faulting effective address. + */ switch(cause){ case 0: - csr[mtval] = addr; + csr[mtval] = static_cast(addr); break; case 2: csr[mtval] = (instr & 0x3)==3?instr:instr&0xffff; @@ -970,10 +977,14 @@ template uint64_t riscv_hart_m_p::e //TODO: implement debug mode behavior // csr[dpc] = addr; // csr[dcsr] = (csr[dcsr] & ~0x1c3) | (1<<6) | PRIV_M; //FIXME: cause should not be 4 (stepi) - csr[mtval] = addr; + csr[mtval] = 0; + break; + case 4: + case 6: + csr[mtval] = fault_data; break; default: - csr[mtval] = fault_data; + csr[mtval] = 0; } fault_data = 0; } else { diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index bb25f2e..5ade158 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -1220,7 +1220,26 @@ template uint64_t riscv_hart_mu_p:: * access, or page-fault exception occurs, mtval is written with the * faulting effective address. */ - csr[utval | (new_priv << 8)] = cause==2?((instr & 0x3)==3?instr:instr&0xffff):fault_data; + switch(cause){ + case 0: + csr[utval | (new_priv << 8)] = static_cast(addr); + break; + case 2: + csr[utval | (new_priv << 8)] = (instr & 0x3)==3?instr:instr&0xffff; + break; + case 3: + //TODO: implement debug mode behavior + // csr[dpc] = addr; + // csr[dcsr] = (csr[dcsr] & ~0x1c3) | (1<<6) | PRIV_M; //FIXME: cause should not be 4 (stepi) + csr[utval | (new_priv << 8)] = 0; + break; + case 4: + case 6: + csr[utval | (new_priv << 8)] = fault_data; + break; + default: + csr[utval | (new_priv << 8)] = 0; + } fault_data = 0; } else { if (this->reg.PRIV != PRIV_M && ((csr[mideleg] >> cause) & 0x1) != 0) From 459794b863c8707071f72667a33a10d7dd1f7c76 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 6 Nov 2021 13:29:11 +0100 Subject: [PATCH 28/37] add proper handling of store access fault (hart_mu_p) --- incl/iss/arch/riscv_hart_mu_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 5ade158..751f87e 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -1235,6 +1235,7 @@ template uint64_t riscv_hart_mu_p:: break; case 4: case 6: + case 7: csr[utval | (new_priv << 8)] = fault_data; break; default: From 49d09a05d77adb7602ea1ed7200e649edc7c7f83 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 7 Nov 2021 16:45:10 +0100 Subject: [PATCH 29/37] fix access rights to debug CSR register (#268) --- incl/iss/arch/riscv_hart_m_p.h | 44 ++++++++++++++++++++++++--------- incl/iss/arch/riscv_hart_mu_p.h | 43 +++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 24 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 9133285..1d69f9a 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -287,7 +287,6 @@ protected: }; std::vector clic_int_reg; -private: iss::status read_csr_reg(unsigned addr, reg_t &val); iss::status write_csr_reg(unsigned addr, reg_t val); iss::status read_null(unsigned addr, reg_t &val); @@ -307,18 +306,23 @@ private: iss::status write_ip(unsigned addr, reg_t val); iss::status read_hartid(unsigned addr, reg_t &val); iss::status write_epc(unsigned addr, reg_t val); - iss::status write_dcsr(unsigned addr, reg_t val); + iss::status write_intstatus(unsigned addr, reg_t val); + iss::status write_intthresh(unsigned addr, reg_t val); + iss::status write_dcsr_dcsr(unsigned addr, reg_t val); + iss::status read_dcsr_reg(unsigned addr, reg_t &val); + iss::status write_dcsr_reg(unsigned addr, reg_t val); + reg_t mhartid_reg{0x0}; std::functionmem_read_cb; std::function mem_write_cb; -protected: void check_interrupt(); bool pmp_check(const access_type type, const uint64_t addr, const unsigned len); uint64_t clic_base_addr{0}; unsigned clic_num_irq{0}; unsigned clic_num_trigger{0}; unsigned mcause_max_irq{16}; + bool debug_mode_active{false}; }; template @@ -389,14 +393,14 @@ riscv_hart_m_p::riscv_hart_m_p() csr_wr_cb[marchid] = &this_class::write_null; csr_wr_cb[mimpid] = &this_class::write_null; if(FEAT & FEAT_DEBUG){ - csr_wr_cb[dscratch0] = &this_class::write_csr_reg; - csr_rd_cb[dscratch0] = &this_class::read_csr_reg; - csr_wr_cb[dscratch1] = &this_class::write_csr_reg; - csr_rd_cb[dscratch1] = &this_class::read_csr_reg; - csr_wr_cb[dpc] = &this_class::write_csr_reg; - csr_rd_cb[dpc] = &this_class::read_csr_reg; - csr_wr_cb[dcsr] = &this_class::write_dcsr; - csr_rd_cb[dcsr] = &this_class::read_csr_reg; + csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; + csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; + csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg; + csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg; + csr_wr_cb[dpc] = &this_class::write_dcsr_reg; + csr_rd_cb[dpc] = &this_class::read_dcsr_reg; + csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; + csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; } } @@ -810,7 +814,9 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::write_dcsr(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_dcsr_dcsr(unsigned addr, reg_t val) { + if(!debug_mode_active) + throw illegal_instruction_fault(this->fault_data); // +-------------- ebreakm // | +---------- stepi // | | +++----- cause @@ -819,6 +825,20 @@ template iss::status riscv_hart_m_p return iss::Ok; } +template iss::status riscv_hart_m_p::read_dcsr_reg(unsigned addr, reg_t &val) { + if(!debug_mode_active) + throw illegal_instruction_fault(this->fault_data); + val = csr[addr]; + return iss::Ok; +} + +template iss::status riscv_hart_m_p::write_dcsr_reg(unsigned addr, reg_t val) { + if(!debug_mode_active) + throw illegal_instruction_fault(this->fault_data); + csr[addr] = val; + return iss::Ok; +} + template iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { if(mem_read_cb) return mem_read_cb(paddr, length, data); diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 751f87e..6d0537c 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -302,7 +302,6 @@ protected: }; std::vector clic_int_reg; -private: iss::status read_csr_reg(unsigned addr, reg_t &val); iss::status write_csr_reg(unsigned addr, reg_t val); iss::status read_null(unsigned addr, reg_t &val); @@ -324,21 +323,23 @@ private: iss::status write_edeleg(unsigned addr, reg_t val); iss::status read_hartid(unsigned addr, reg_t &val); iss::status write_epc(unsigned addr, reg_t val); - iss::status write_dcsr(unsigned addr, reg_t val); iss::status write_intstatus(unsigned addr, reg_t val); iss::status write_intthresh(unsigned addr, reg_t val); + iss::status write_dcsr_dcsr(unsigned addr, reg_t val); + iss::status read_dcsr_reg(unsigned addr, reg_t &val); + iss::status write_dcsr_reg(unsigned addr, reg_t val); reg_t mhartid_reg{0x0}; std::functionmem_read_cb; std::function mem_write_cb; -protected: void check_interrupt(); bool pmp_check(const access_type type, const uint64_t addr, const unsigned len); uint64_t clic_base_addr{0}; unsigned clic_num_irq{0}; unsigned clic_num_trigger{0}; unsigned mcause_max_irq{16}; + bool debug_mode_active{false}; }; template @@ -464,14 +465,14 @@ riscv_hart_mu_p::riscv_hart_mu_p() mcause_max_irq=clic_num_irq+16; } if(FEAT & FEAT_DEBUG){ - csr_wr_cb[dscratch0] = &this_class::write_csr_reg; - csr_rd_cb[dscratch0] = &this_class::read_csr_reg; - csr_wr_cb[dscratch1] = &this_class::write_csr_reg; - csr_rd_cb[dscratch1] = &this_class::read_csr_reg; - csr_wr_cb[dpc] = &this_class::write_csr_reg; - csr_rd_cb[dpc] = &this_class::read_csr_reg; - csr_wr_cb[dcsr] = &this_class::write_dcsr; - csr_rd_cb[dcsr] = &this_class::read_csr_reg; + csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; + csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; + csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg; + csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg; + csr_wr_cb[dpc] = &this_class::write_dcsr_reg; + csr_rd_cb[dpc] = &this_class::read_dcsr_reg; + csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; + csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; } } @@ -977,7 +978,9 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_dcsr(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_dcsr_dcsr(unsigned addr, reg_t val) { + if(!debug_mode_active) + throw illegal_instruction_fault(this->fault_data); // +-------------- ebreakm // | +---------- stepi // | | +++----- cause @@ -985,6 +988,22 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_dcsr_reg(unsigned addr, reg_t &val) { + if(!debug_mode_active) + throw illegal_instruction_fault(this->fault_data); + val = csr[addr]; + return iss::Ok; +} + +template iss::status riscv_hart_mu_p::write_dcsr_reg(unsigned addr, reg_t val) { + if(!debug_mode_active) + throw illegal_instruction_fault(this->fault_data); + csr[addr] = val; + return iss::Ok; +} + + template iss::status riscv_hart_mu_p::write_intthresh(unsigned addr, reg_t val) { csr[addr]= val &0xff; From c42e33650928c97fe49fd2d36851d12aca07a497 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 7 Nov 2021 17:48:44 +0100 Subject: [PATCH 30/37] fix proper debug mode handling (#267 & #268) --- gen_input/CoreDSL-Instruction-Set-Description | 2 +- gen_input/templates/interp/CORENAME.cpp.gtl | 10 +- incl/iss/arch/riscv_hart_m_p.h | 28 +- incl/iss/arch/riscv_hart_mu_p.h | 27 +- incl/iss/arch/tgc_c.h | 112 ++-- src/iss/tgc_c.cpp | 8 +- src/vm/interp/vm_tgc_c.cpp | 500 ++++++++++-------- 7 files changed, 386 insertions(+), 301 deletions(-) diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description index e7aaec6..b005607 160000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ b/gen_input/CoreDSL-Instruction-Set-Description @@ -1 +1 @@ -Subproject commit e7aaec6ad9336bd83b4da63dd0c96f8d11887661 +Subproject commit b005607fc30c4467683b6044eaca7eb378061b53 diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 53cffed..7cf5c47 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -29,7 +29,13 @@ * POSSIBILITY OF SUCH DAMAGE. * *******************************************************************************/ +<% +import com.minres.coredsl.util.BigIntegerWithRadix +def nativeTypeSize(int size){ + if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64; +} +%> #include "../fp_functions.h" #include #include @@ -204,8 +210,8 @@ private: } // used registers<%instr.usedVariables.each{ k,v-> if(v.isArray) {%> - auto* ${k} = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::${k}0]);<% }else{ %> - auto* ${k} = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::${k}]); + auto* ${k} = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::${k}0]);<% }else{ %> + auto* ${k} = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::${k}]); <%}}%>// calculate next pc value *NEXT_PC = *PC + ${instr.length/8}; // execute instruction diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 1d69f9a..e5dc148 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -311,6 +311,8 @@ protected: iss::status write_dcsr_dcsr(unsigned addr, reg_t val); iss::status read_dcsr_reg(unsigned addr, reg_t &val); iss::status write_dcsr_reg(unsigned addr, reg_t val); + iss::status read_dpc_reg(unsigned addr, reg_t &val); + iss::status write_dpc_reg(unsigned addr, reg_t val); reg_t mhartid_reg{0x0}; std::functionmem_read_cb; @@ -322,7 +324,7 @@ protected: unsigned clic_num_irq{0}; unsigned clic_num_trigger{0}; unsigned mcause_max_irq{16}; - bool debug_mode_active{false}; + inline bool debug_mode_active() {return this->reg.PRIV&0x4;} }; template @@ -397,8 +399,8 @@ riscv_hart_m_p::riscv_hart_m_p() csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg; csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg; - csr_wr_cb[dpc] = &this_class::write_dcsr_reg; - csr_rd_cb[dpc] = &this_class::read_dcsr_reg; + csr_wr_cb[dpc] = &this_class::write_dpc_reg; + csr_rd_cb[dpc] = &this_class::read_dpc_reg; csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; } @@ -815,7 +817,7 @@ template iss::status riscv_hart_m_p } template iss::status riscv_hart_m_p::write_dcsr_dcsr(unsigned addr, reg_t val) { - if(!debug_mode_active) + if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); // +-------------- ebreakm // | +---------- stepi @@ -826,19 +828,33 @@ template iss::status riscv_hart_m_p } template iss::status riscv_hart_m_p::read_dcsr_reg(unsigned addr, reg_t &val) { - if(!debug_mode_active) + if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); val = csr[addr]; return iss::Ok; } template iss::status riscv_hart_m_p::write_dcsr_reg(unsigned addr, reg_t val) { - if(!debug_mode_active) + if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); csr[addr] = val; return iss::Ok; } +template iss::status riscv_hart_m_p::read_dpc_reg(unsigned addr, reg_t &val) { + if(!debug_mode_active()) + throw illegal_instruction_fault(this->fault_data); + val = this->reg.DPC; + return iss::Ok; +} + +template iss::status riscv_hart_m_p::write_dpc_reg(unsigned addr, reg_t val) { + if(!debug_mode_active()) + throw illegal_instruction_fault(this->fault_data); + this->reg.DPC = val; + return iss::Ok; +} + template iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { if(mem_read_cb) return mem_read_cb(paddr, length, data); diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 6d0537c..a0d088b 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -328,6 +328,8 @@ protected: iss::status write_dcsr_dcsr(unsigned addr, reg_t val); iss::status read_dcsr_reg(unsigned addr, reg_t &val); iss::status write_dcsr_reg(unsigned addr, reg_t val); + iss::status read_dpc_reg(unsigned addr, reg_t &val); + iss::status write_dpc_reg(unsigned addr, reg_t val); reg_t mhartid_reg{0x0}; std::functionmem_read_cb; @@ -339,7 +341,7 @@ protected: unsigned clic_num_irq{0}; unsigned clic_num_trigger{0}; unsigned mcause_max_irq{16}; - bool debug_mode_active{false}; + inline bool debug_mode_active() {return this->reg.PRIV&0x4;} }; template @@ -469,8 +471,8 @@ riscv_hart_mu_p::riscv_hart_mu_p() csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg; csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg; - csr_wr_cb[dpc] = &this_class::write_dcsr_reg; - csr_rd_cb[dpc] = &this_class::read_dcsr_reg; + csr_wr_cb[dpc] = &this_class::write_dpc_reg; + csr_rd_cb[dpc] = &this_class::read_dpc_reg; csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr; csr_rd_cb[dcsr] = &this_class::read_dcsr_reg; } @@ -979,7 +981,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_dcsr_dcsr(unsigned addr, reg_t val) { - if(!debug_mode_active) + if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); // +-------------- ebreakm // | +---------- stepi @@ -990,19 +992,32 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_dcsr_reg(unsigned addr, reg_t &val) { - if(!debug_mode_active) + if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); val = csr[addr]; return iss::Ok; } template iss::status riscv_hart_mu_p::write_dcsr_reg(unsigned addr, reg_t val) { - if(!debug_mode_active) + if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); csr[addr] = val; return iss::Ok; } +template iss::status riscv_hart_m_p::read_dpc_reg(unsigned addr, reg_t &val) { + if(!debug_mode_active()) + throw illegal_instruction_fault(this->fault_data); + val = this->reg.DPC; + return iss::Ok; +} + +template iss::status riscv_hart_m_p::write_dpc_reg(unsigned addr, reg_t val) { + if(!debug_mode_active()) + throw illegal_instruction_fault(this->fault_data); + this->reg.DPC = val; + return iss::Ok; +} template iss::status riscv_hart_mu_p::write_intthresh(unsigned addr, reg_t val) { diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index e7e440a..2efcaf9 100644 --- a/incl/iss/arch/tgc_c.h +++ b/incl/iss/arch/tgc_c.h @@ -47,18 +47,18 @@ template <> struct traits { constexpr static char const* const core_type = "TGC_C"; - static constexpr std::array reg_names{ - {"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 reg_names{ + {"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", "DPC"}}; - static constexpr std::array 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"}}; + static constexpr std::array 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, 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; enum reg_e { - 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, NUM_REGS, + 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, DPC, NUM_REGS, TRAP_STATE=NUM_REGS, PENDING_TRAP, ICOUNT, @@ -76,11 +76,11 @@ template <> struct traits { using phys_addr_t = iss::typed_addr_t; - static constexpr std::array 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,64,64,64}}; + static constexpr std::array 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 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,153,161}}; + static constexpr std::array 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 const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); @@ -133,51 +133,52 @@ template <> struct traits { SRET = 41, MRET = 42, WFI = 43, - CSRRW = 44, - CSRRS = 45, - CSRRC = 46, - CSRRWI = 47, - CSRRSI = 48, - CSRRCI = 49, - FENCE_I = 50, - MUL = 51, - MULH = 52, - MULHSU = 53, - MULHU = 54, - DIV = 55, - DIVU = 56, - REM = 57, - REMU = 58, - CADDI4SPN = 59, - CLW = 60, - CSW = 61, - CADDI = 62, - CNOP = 63, - CJAL = 64, - CLI = 65, - CLUI = 66, - CADDI16SP = 67, - __reserved_clui = 68, - CSRLI = 69, - CSRAI = 70, - CANDI = 71, - CSUB = 72, - CXOR = 73, - COR = 74, - CAND = 75, - CJ = 76, - CBEQZ = 77, - CBNEZ = 78, - CSLLI = 79, - CLWSP = 80, - CMV = 81, - CJR = 82, - __reserved_cmv = 83, - CADD = 84, - CJALR = 85, - CEBREAK = 86, - CSWSP = 87, - DII = 88, + DRET = 44, + CSRRW = 45, + CSRRS = 46, + CSRRC = 47, + CSRRWI = 48, + CSRRSI = 49, + CSRRCI = 50, + FENCE_I = 51, + MUL = 52, + MULH = 53, + MULHSU = 54, + MULHU = 55, + DIV = 56, + DIVU = 57, + REM = 58, + REMU = 59, + CADDI4SPN = 60, + CLW = 61, + CSW = 62, + CADDI = 63, + CNOP = 64, + CJAL = 65, + CLI = 66, + CLUI = 67, + CADDI16SP = 68, + __reserved_clui = 69, + CSRLI = 70, + CSRAI = 71, + CANDI = 72, + CSUB = 73, + CXOR = 74, + COR = 75, + CAND = 76, + CJ = 77, + CBEQZ = 78, + CBNEZ = 79, + CSLLI = 80, + CLWSP = 81, + CMV = 82, + CJR = 83, + __reserved_cmv = 84, + CADD = 85, + CJALR = 86, + CEBREAK = 87, + CSWSP = 88, + DII = 89, MAX_OPCODE }; }; @@ -253,7 +254,8 @@ protected: uint32_t X31 = 0; uint32_t PC = 0; uint32_t NEXT_PC = 0; - uint8_t PRIV = 0; + uint8_t PRIV = 0; + uint32_t DPC = 0; uint32_t trap_state = 0, pending_trap = 0; uint64_t icount = 0; uint64_t cycle = 0; diff --git a/src/iss/tgc_c.cpp b/src/iss/tgc_c.cpp index 1dd9e89..b5e8fed 100644 --- a/src/iss/tgc_c.cpp +++ b/src/iss/tgc_c.cpp @@ -39,10 +39,10 @@ using namespace iss::arch; -constexpr std::array iss::arch::traits::reg_names; -constexpr std::array iss::arch::traits::reg_aliases; -constexpr std::array iss::arch::traits::reg_bit_widths; -constexpr std::array iss::arch::traits::reg_byte_offsets; +constexpr std::array iss::arch::traits::reg_names; +constexpr std::array iss::arch::traits::reg_aliases; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; tgc_c::tgc_c() { reg.icount = 0; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 7bbcf36..ad50b5a 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -180,7 +180,7 @@ private: compile_func op; }; - const std::array instr_descr = {{ + const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */ /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, @@ -270,6 +270,8 @@ private: {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__mret}, /* instruction WFI */ {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, &this_class::__wfi}, + /* instruction DRET */ + {32, 0b01111011001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__dret}, /* instruction CSRRW */ {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, &this_class::__csrrw}, /* instruction CSRRS */ @@ -2209,8 +2211,8 @@ private: return pc; } - /* instruction 44: CSRRW */ - compile_ret_t __csrrw(virt_addr_t& pc, code_word_t instr){ + /* instruction 44: DRET */ + compile_ret_t __dret(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -2218,6 +2220,50 @@ private: auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 44); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "dret"); + + } + // used registers + auto* PRIV = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PRIV]); + + auto* DPC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::DPC]); + // calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(*PRIV < 4) raise(0, 2); + else { + pc_assign(*NEXT_PC) = *DPC; + *PRIV &= 0x3; + } + } + } catch(...){} + // post execution stuff + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); + // trap check + if(*trap_state!=0){ + super::core.enter_trap(*trap_state, pc.val, instr); + } else { + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; + return pc; + } + + /* instruction 45: CSRRW */ + compile_ret_t __csrrw(virt_addr_t& pc, code_word_t instr){ + // pre execution stuff + auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *PC=*NEXT_PC; + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 45); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint16_t csr = ((bit_sub<20,12>(instr))); @@ -2247,7 +2293,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2260,7 +2306,7 @@ private: return pc; } - /* instruction 45: CSRRS */ + /* instruction 46: CSRRS */ compile_ret_t __csrrs(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2268,7 +2314,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 45); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 46); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint16_t csr = ((bit_sub<20,12>(instr))); @@ -2293,7 +2339,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2306,7 +2352,7 @@ private: return pc; } - /* instruction 46: CSRRC */ + /* instruction 47: CSRRC */ compile_ret_t __csrrc(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2314,7 +2360,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 46); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 47); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint16_t csr = ((bit_sub<20,12>(instr))); @@ -2339,7 +2385,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2352,7 +2398,7 @@ private: return pc; } - /* instruction 47: CSRRWI */ + /* instruction 48: CSRRWI */ compile_ret_t __csrrwi(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2360,7 +2406,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 47); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 48); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); uint16_t csr = ((bit_sub<20,12>(instr))); @@ -2384,7 +2430,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2397,7 +2443,7 @@ private: return pc; } - /* instruction 48: CSRRSI */ + /* instruction 49: CSRRSI */ compile_ret_t __csrrsi(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2405,7 +2451,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 48); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 49); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); uint16_t csr = ((bit_sub<20,12>(instr))); @@ -2429,7 +2475,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2442,7 +2488,7 @@ private: return pc; } - /* instruction 49: CSRRCI */ + /* instruction 50: CSRRCI */ compile_ret_t __csrrci(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2450,7 +2496,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 49); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 50); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); uint16_t csr = ((bit_sub<20,12>(instr))); @@ -2474,7 +2520,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2487,7 +2533,7 @@ private: return pc; } - /* instruction 50: FENCE_I */ + /* instruction 51: FENCE_I */ compile_ret_t __fence_i(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2495,7 +2541,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 50); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 51); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint16_t imm = ((bit_sub<20,12>(instr))); @@ -2514,7 +2560,7 @@ private: writeSpace2(traits::FENCE, traits::fencei, imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2527,7 +2573,7 @@ private: return pc; } - /* instruction 51: MUL */ + /* instruction 52: MUL */ compile_ret_t __mul(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2535,7 +2581,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 51); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 52); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2560,7 +2606,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2573,7 +2619,7 @@ private: return pc; } - /* instruction 52: MULH */ + /* instruction 53: MULH */ compile_ret_t __mulh(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2581,7 +2627,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 52); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 53); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2606,7 +2652,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2619,7 +2665,7 @@ private: return pc; } - /* instruction 53: MULHSU */ + /* instruction 54: MULHSU */ compile_ret_t __mulhsu(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2627,7 +2673,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 53); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 54); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2652,7 +2698,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2665,7 +2711,7 @@ private: return pc; } - /* instruction 54: MULHU */ + /* instruction 55: MULHU */ compile_ret_t __mulhu(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2673,7 +2719,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 54); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 55); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2698,7 +2744,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2711,7 +2757,7 @@ private: return pc; } - /* instruction 55: DIV */ + /* instruction 56: DIV */ compile_ret_t __div(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2719,7 +2765,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 55); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 56); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2748,7 +2794,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2761,7 +2807,7 @@ private: return pc; } - /* instruction 56: DIVU */ + /* instruction 57: DIVU */ compile_ret_t __divu(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2769,7 +2815,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 56); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 57); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2794,7 +2840,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2807,7 +2853,7 @@ private: return pc; } - /* instruction 57: REM */ + /* instruction 58: REM */ compile_ret_t __rem(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2815,7 +2861,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 57); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 58); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2844,7 +2890,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2857,7 +2903,7 @@ private: return pc; } - /* instruction 58: REMU */ + /* instruction 59: REMU */ compile_ret_t __remu(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2865,7 +2911,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 58); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 59); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2890,7 +2936,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2903,7 +2949,7 @@ private: return pc; } - /* instruction 59: CADDI4SPN */ + /* instruction 60: CADDI4SPN */ compile_ret_t __caddi4spn(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2911,7 +2957,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 59); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 60); uint8_t rd = ((bit_sub<2,3>(instr))); uint16_t imm = ((bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4)); if(this->disass_enabled){ @@ -2931,7 +2977,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2944,7 +2990,7 @@ private: return pc; } - /* instruction 60: CLW */ + /* instruction 61: CLW */ compile_ret_t __clw(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2952,7 +2998,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 60); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 61); uint8_t rd = ((bit_sub<2,3>(instr))); uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -2975,7 +3021,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -2988,7 +3034,7 @@ private: return pc; } - /* instruction 61: CSW */ + /* instruction 62: CSW */ compile_ret_t __csw(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -2996,7 +3042,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 61); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 62); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -3019,7 +3065,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3032,7 +3078,7 @@ private: return pc; } - /* instruction 62: CADDI */ + /* instruction 63: CADDI */ compile_ret_t __caddi(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3040,7 +3086,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 62); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 63); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3059,7 +3105,7 @@ private: *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3072,7 +3118,7 @@ private: return pc; } - /* instruction 63: CNOP */ + /* instruction 64: CNOP */ compile_ret_t __cnop(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3080,7 +3126,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 63); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 64); uint8_t nzimm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3095,7 +3141,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3108,7 +3154,7 @@ private: return pc; } - /* instruction 64: CJAL */ + /* instruction 65: CJAL */ compile_ret_t __cjal(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3116,7 +3162,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 64); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 65); uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3137,7 +3183,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3150,7 +3196,7 @@ private: return pc; } - /* instruction 65: CLI */ + /* instruction 66: CLI */ compile_ret_t __cli(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3158,7 +3204,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 65); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 66); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3179,7 +3225,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3192,7 +3238,7 @@ private: return pc; } - /* instruction 66: CLUI */ + /* instruction 67: CLUI */ compile_ret_t __clui(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3200,7 +3246,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 66); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 67); uint32_t imm = ((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3222,7 +3268,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3235,7 +3281,7 @@ private: return pc; } - /* instruction 67: CADDI16SP */ + /* instruction 68: CADDI16SP */ compile_ret_t __caddi16sp(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3243,7 +3289,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 67); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 68); uint16_t nzimm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3262,41 +3308,6 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); - // trap check - if(*trap_state!=0){ - super::core.enter_trap(*trap_state, pc.val, instr); - } else { - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; - } - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; - pc.val=*NEXT_PC; - return pc; - } - - /* instruction 68: __reserved_clui */ - compile_ret_t ____reserved_clui(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); - auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - *PC=*NEXT_PC; - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 68); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "__reserved_clui"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - } catch(...){} - // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); // trap check if(*trap_state!=0){ @@ -3310,8 +3321,8 @@ private: return pc; } - /* instruction 69: CSRLI */ - compile_ret_t __csrli(virt_addr_t& pc, code_word_t instr){ + /* instruction 69: __reserved_clui */ + compile_ret_t ____reserved_clui(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -3319,6 +3330,41 @@ private: auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 69); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "__reserved_clui"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + raise(0, 2); + } catch(...){} + // post execution stuff + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); + // trap check + if(*trap_state!=0){ + super::core.enter_trap(*trap_state, pc.val, instr); + } else { + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; + return pc; + } + + /* instruction 70: CSRLI */ + compile_ret_t __csrli(virt_addr_t& pc, code_word_t instr){ + // pre execution stuff + auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *PC=*NEXT_PC; + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 70); uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3340,7 +3386,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3353,7 +3399,7 @@ private: return pc; } - /* instruction 70: CSRAI */ + /* instruction 71: CSRAI */ compile_ret_t __csrai(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3361,7 +3407,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 70); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 71); uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3387,7 +3433,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3400,7 +3446,7 @@ private: return pc; } - /* instruction 71: CANDI */ + /* instruction 72: CANDI */ compile_ret_t __candi(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3408,7 +3454,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 71); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 72); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3430,7 +3476,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3443,7 +3489,7 @@ private: return pc; } - /* instruction 72: CSUB */ + /* instruction 73: CSUB */ compile_ret_t __csub(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3451,7 +3497,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 72); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 73); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3473,7 +3519,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3486,7 +3532,7 @@ private: return pc; } - /* instruction 73: CXOR */ + /* instruction 74: CXOR */ compile_ret_t __cxor(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3494,7 +3540,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 73); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 74); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3516,7 +3562,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3529,7 +3575,7 @@ private: return pc; } - /* instruction 74: COR */ + /* instruction 75: COR */ compile_ret_t __cor(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3537,7 +3583,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 74); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 75); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3559,7 +3605,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3572,7 +3618,7 @@ private: return pc; } - /* instruction 75: CAND */ + /* instruction 76: CAND */ compile_ret_t __cand(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3580,7 +3626,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 75); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 76); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3602,7 +3648,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3615,7 +3661,7 @@ private: return pc; } - /* instruction 76: CJ */ + /* instruction 77: CJ */ compile_ret_t __cj(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3623,7 +3669,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 76); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 77); uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3640,7 +3686,7 @@ private: pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3653,7 +3699,7 @@ private: return pc; } - /* instruction 77: CBEQZ */ + /* instruction 78: CBEQZ */ compile_ret_t __cbeqz(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3661,7 +3707,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 77); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 78); uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3680,7 +3726,7 @@ private: if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3693,7 +3739,7 @@ private: return pc; } - /* instruction 78: CBNEZ */ + /* instruction 79: CBNEZ */ compile_ret_t __cbnez(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3701,7 +3747,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 78); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 79); uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ @@ -3720,7 +3766,7 @@ private: if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3733,7 +3779,7 @@ private: return pc; } - /* instruction 79: CSLLI */ + /* instruction 80: CSLLI */ compile_ret_t __cslli(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3741,7 +3787,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 79); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 80); uint8_t nzuimm = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3760,7 +3806,7 @@ private: if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3773,7 +3819,7 @@ private: return pc; } - /* instruction 80: CLWSP */ + /* instruction 81: CLWSP */ compile_ret_t __clwsp(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3781,7 +3827,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 80); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 81); uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3804,7 +3850,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3817,7 +3863,7 @@ private: return pc; } - /* instruction 81: CMV */ + /* instruction 82: CMV */ compile_ret_t __cmv(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3825,7 +3871,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 81); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 82); uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3844,7 +3890,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3857,7 +3903,7 @@ private: return pc; } - /* instruction 82: CJR */ + /* instruction 83: CJR */ compile_ret_t __cjr(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3865,7 +3911,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 82); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 83); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -3884,40 +3930,6 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); - // trap check - if(*trap_state!=0){ - super::core.enter_trap(*trap_state, pc.val, instr); - } else { - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; - } - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; - pc.val=*NEXT_PC; - return pc; - } - - /* instruction 83: __reserved_cmv */ - compile_ret_t ____reserved_cmv(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); - auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - *PC=*NEXT_PC; - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 83); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "__reserved_cmv"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - } catch(...){} - // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); // trap check if(*trap_state!=0){ @@ -3931,8 +3943,8 @@ private: return pc; } - /* instruction 84: CADD */ - compile_ret_t __cadd(virt_addr_t& pc, code_word_t instr){ + /* instruction 84: __reserved_cmv */ + compile_ret_t ____reserved_cmv(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -3940,6 +3952,40 @@ private: auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 84); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "__reserved_cmv"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + raise(0, 2); + } catch(...){} + // post execution stuff + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); + // trap check + if(*trap_state!=0){ + super::core.enter_trap(*trap_state, pc.val, instr); + } else { + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; + return pc; + } + + /* instruction 85: CADD */ + compile_ret_t __cadd(virt_addr_t& pc, code_word_t instr){ + // pre execution stuff + auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *PC=*NEXT_PC; + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 85); uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3958,7 +4004,7 @@ private: if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -3971,7 +4017,7 @@ private: return pc; } - /* instruction 85: CJALR */ + /* instruction 86: CJALR */ compile_ret_t __cjalr(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -3979,7 +4025,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 85); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 86); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -4001,40 +4047,6 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); - // trap check - if(*trap_state!=0){ - super::core.enter_trap(*trap_state, pc.val, instr); - } else { - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; - } - (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; - pc.val=*NEXT_PC; - return pc; - } - - /* instruction 86: CEBREAK */ - compile_ret_t __cebreak(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); - auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - *PC=*NEXT_PC; - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 86); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "cebreak"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 3); - } catch(...){} - // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); // trap check if(*trap_state!=0){ @@ -4048,8 +4060,8 @@ private: return pc; } - /* instruction 87: CSWSP */ - compile_ret_t __cswsp(virt_addr_t& pc, code_word_t instr){ + /* instruction 87: CEBREAK */ + compile_ret_t __cebreak(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -4057,6 +4069,40 @@ private: auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 87); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "cebreak"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + raise(0, 3); + } catch(...){} + // post execution stuff + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); + // trap check + if(*trap_state!=0){ + super::core.enter_trap(*trap_state, pc.val, instr); + } else { + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]))++; + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]))++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; + return pc; + } + + /* instruction 88: CSWSP */ + compile_ret_t __cswsp(virt_addr_t& pc, code_word_t instr){ + // pre execution stuff + auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + auto NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *PC=*NEXT_PC; + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 88); uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); if(this->disass_enabled){ @@ -4078,7 +4124,7 @@ private: } } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 88); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); @@ -4091,7 +4137,7 @@ private: return pc; } - /* instruction 88: DII */ + /* instruction 89: DII */ compile_ret_t __dii(virt_addr_t& pc, code_word_t instr){ // pre execution stuff auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); @@ -4099,7 +4145,7 @@ private: *PC=*NEXT_PC; auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); *trap_state = *reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PENDING_TRAP]); - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 88); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 89); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "dii"); @@ -4112,7 +4158,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 88); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 89); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); From bfa8166223f629dd6c1820580c0d724c7a9745c7 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 8 Nov 2021 10:44:33 +0100 Subject: [PATCH 31/37] fix wrong template class name --- incl/iss/arch/riscv_hart_mu_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index a0d088b..038c841 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -1005,14 +1005,14 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_m_p::read_dpc_reg(unsigned addr, reg_t &val) { +template iss::status riscv_hart_mu_p::read_dpc_reg(unsigned addr, reg_t &val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); val = this->reg.DPC; return iss::Ok; } -template iss::status riscv_hart_m_p::write_dpc_reg(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_dpc_reg(unsigned addr, reg_t val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); this->reg.DPC = val; From fd98ad95f6f417fdfa0e5f8686f84b8cf32eceac Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 9 Nov 2021 15:55:22 +0100 Subject: [PATCH 32/37] rework PMP check and fix MISA for TGC_D --- gen_input/TGC_D.core_desc | 2 +- incl/iss/arch/riscv_hart_mu_p.h | 54 +++++++++++++++------------------ 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/gen_input/TGC_D.core_desc b/gen_input/TGC_D.core_desc index 1187485..c4d9c54 100644 --- a/gen_input/TGC_D.core_desc +++ b/gen_input/TGC_D.core_desc @@ -7,7 +7,7 @@ Core TGC_D provides RV32I, Zicsr, Zifencei, RV32M, RV32IC { XLEN=32; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - unsigned MISA_VAL = 0b01000000000000000001000100000100; + unsigned MISA_VAL = 0b01000000000100000011000100000100; unsigned MARCHID_VAL = 0x80000004; } } diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 038c841..f9e6ab2 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -554,42 +554,36 @@ template bool riscv_hart_mu_p::pmp_ constexpr auto PMP_TOR =0x1U; constexpr auto PMP_NA4 =0x2U; constexpr auto PMP_NAPOT =0x3U; - reg_t base = 0; + constexpr auto pmp_num_regs = 16; + reg_t tor_base = 0; auto any_active = false; - for (size_t i = 0; i < 16; i++) { - reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT; + auto lower_addr = addr >>2; + auto upper_addr = (addr+len-1)>>2; + for (size_t i = 0; i < pmp_num_regs; i++) { uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4); + uint8_t cfg_next = i==(pmp_num_regs-1)? 0 : csr[pmpcfg0+((i+1)/4)]>>((i+1)%4); + auto pmpaddr = csr[pmpaddr0+i]; if (cfg & PMP_A) { any_active=true; - auto pmp_a = (cfg & PMP_A) >> 3; - 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 - 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; - 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; - } - if (any_match) { - // If the PMP matches only a strict subset of the access, fail it - if (!all_match) - return false; - return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || - (type == access_type::READ && (cfg & PMP_R)) || - (type == access_type::WRITE && (cfg & PMP_W)) || - (type == access_type::FETCH && (cfg & PMP_X)); + auto is_tor = bit_sub<3, 2>(cfg) == PMP_TOR; + auto is_napot = bit_sub<4, 1>(cfg) && bit_sub<3, 2>(cfg_next)!= PMP_TOR; + if(is_napot) { + reg_t mask = bit_sub<3, 1>(cfg)?~( pmpaddr & ~(pmpaddr + 1)): 0x3fffffff; + auto mpmpaddr = pmpaddr & mask; + if((lower_addr&mask) == mpmpaddr && (upper_addr&mask)==mpmpaddr) + return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || + (type == access_type::READ && (cfg & PMP_R)) || + (type == access_type::WRITE && (cfg & PMP_W)) || + (type == access_type::FETCH && (cfg & PMP_X)); + } else if(is_tor) { + if(lower_addr>=tor_base && upper_addr<=pmpaddr) + return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || + (type == access_type::READ && (cfg & PMP_R)) || + (type == access_type::WRITE && (cfg & PMP_W)) || + (type == access_type::FETCH && (cfg & PMP_X)); } } - base = tor; + tor_base = pmpaddr; } return !any_active || this->reg.PRIV == PRIV_M; } From 2d7973520b00717eebf7064caab5cfe4564450a1 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 9 Nov 2021 19:47:34 +0100 Subject: [PATCH 33/37] fix mip handling --- incl/iss/arch/riscv_hart_m_p.h | 14 ++++++++------ incl/iss/arch/riscv_hart_mu_p.h | 14 ++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index e5dc148..4a7046a 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -781,13 +781,14 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t &val) { - val = csr[mie]; +template iss::status riscv_hart_m_p::read_hartid(unsigned addr, reg_t &val) { + val = mhartid_reg; return iss::Ok; } -template iss::status riscv_hart_m_p::read_hartid(unsigned addr, reg_t &val) { - val = mhartid_reg; +template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t &val) { + auto mask = get_irq_mask(); + val = csr[mie] & mask; return iss::Ok; } @@ -799,13 +800,14 @@ template iss::status riscv_hart_m_p } template iss::status riscv_hart_m_p::read_ip(unsigned addr, reg_t &val) { - val = csr[mip]; + auto mask = get_irq_mask(); + val = csr[mip] & mask; return iss::Ok; } template iss::status riscv_hart_m_p::write_ip(unsigned addr, reg_t val) { auto mask = get_irq_mask(); - mask &= ~(1 << 7); // MTIP is read only + mask &= 0xf; // only xSIP is writable csr[mip] = (csr[mip] & ~mask) | (val & mask); check_interrupt(); return iss::Ok; diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index f9e6ab2..b1ed4f1 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -181,7 +181,7 @@ public: }; using hart_state_type = hart_state; - constexpr reg_t get_irq_wrmask(size_t mode) { + constexpr reg_t get_irq_mask(size_t mode) { std::array m = {{ 0b000100010001, // U mode 0b001100110011, // S mode @@ -925,7 +925,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_ie(unsigned addr, reg_t &val) { - auto mask = get_irq_wrmask((addr >> 8) & 0x3); + auto mask = get_irq_mask((addr >> 8) & 0x3); val = csr[mie] & mask; if(this->reg.PRIV!=3) val &= csr[mideleg]; @@ -933,14 +933,14 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_ie(unsigned addr, reg_t val) { - auto mask = get_irq_wrmask((addr >> 8) & 0x3); + auto mask = get_irq_mask((addr >> 8) & 0x3); csr[mie] = (csr[mie] & ~mask) | (val & mask); check_interrupt(); return iss::Ok; } template iss::status riscv_hart_mu_p::read_ip(unsigned addr, reg_t &val) { - auto mask = get_irq_wrmask((addr >> 8) & 0x3); + auto mask = get_irq_mask((addr >> 8) & 0x3); val = csr[mip] & mask; if(this->reg.PRIV!=3) val &= csr[mideleg]; @@ -948,10 +948,8 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_ip(unsigned addr, reg_t val) { - auto mask = get_irq_wrmask((addr >> 8) & 0x3); - mask &= ~(8 << 4); // MTIP is read only - if(this->reg.PRIV!=3) - mask &= ~(3 << 4); // STIP and UTIP are read only in user and supervisor mode + auto mask = get_irq_mask((addr >> 8) & 0x3); + mask &= 0xf; // only xSIP is writable csr[mip] = (csr[mip] & ~mask) | (val & mask); check_interrupt(); return iss::Ok; From f90c48e88142347a53e5c49c0f2f181bd069ce6c Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 11 Nov 2021 08:33:35 +0100 Subject: [PATCH 34/37] adapt to changed define names --- src/sysc/core_complex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 171eaaa..268c9e8 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -70,7 +70,7 @@ using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p(backend, gdb_port, hart_id); } else -#ifdef WITH_SCV +#ifdef HAS_SCV #include #else #include From 43d7b9990516ac62bc7586cba11b92e4fcbcc32a Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 11 Nov 2021 09:58:19 +0100 Subject: [PATCH 35/37] revert pmp check implementation --- incl/iss/arch/riscv_hart_mu_p.h | 85 +++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index b1ed4f1..2444cd7 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -554,37 +554,74 @@ template bool riscv_hart_mu_p::pmp_ constexpr auto PMP_TOR =0x1U; constexpr auto PMP_NA4 =0x2U; constexpr auto PMP_NAPOT =0x3U; - constexpr auto pmp_num_regs = 16; - reg_t tor_base = 0; + reg_t base = 0; auto any_active = false; - auto lower_addr = addr >>2; - auto upper_addr = (addr+len-1)>>2; - for (size_t i = 0; i < pmp_num_regs; i++) { + 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); - uint8_t cfg_next = i==(pmp_num_regs-1)? 0 : csr[pmpcfg0+((i+1)/4)]>>((i+1)%4); - auto pmpaddr = csr[pmpaddr0+i]; if (cfg & PMP_A) { any_active=true; - auto is_tor = bit_sub<3, 2>(cfg) == PMP_TOR; - auto is_napot = bit_sub<4, 1>(cfg) && bit_sub<3, 2>(cfg_next)!= PMP_TOR; - if(is_napot) { - reg_t mask = bit_sub<3, 1>(cfg)?~( pmpaddr & ~(pmpaddr + 1)): 0x3fffffff; - auto mpmpaddr = pmpaddr & mask; - if((lower_addr&mask) == mpmpaddr && (upper_addr&mask)==mpmpaddr) - return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || - (type == access_type::READ && (cfg & PMP_R)) || - (type == access_type::WRITE && (cfg & PMP_W)) || - (type == access_type::FETCH && (cfg & PMP_X)); - } else if(is_tor) { - if(lower_addr>=tor_base && upper_addr<=pmpaddr) - return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || - (type == access_type::READ && (cfg & PMP_R)) || - (type == access_type::WRITE && (cfg & PMP_W)) || - (type == access_type::FETCH && (cfg & PMP_X)); + auto pmp_a = (cfg & PMP_A) >> 3; + 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 + 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; + 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; + } + if (any_match) { + // If the PMP matches only a strict subset of the access, fail it + if (!all_match) + return false; + return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || + (type == access_type::READ && (cfg & PMP_R)) || + (type == access_type::WRITE && (cfg & PMP_W)) || + (type == access_type::FETCH && (cfg & PMP_X)); } } - tor_base = pmpaddr; + base = tor; } +// constexpr auto pmp_num_regs = 16; +// reg_t tor_base = 0; +// auto any_active = false; +// auto lower_addr = addr >>2; +// auto upper_addr = (addr+len-1)>>2; +// for (size_t i = 0; i < pmp_num_regs; i++) { +// uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4); +// uint8_t cfg_next = i==(pmp_num_regs-1)? 0 : csr[pmpcfg0+((i+1)/4)]>>((i+1)%4); +// auto pmpaddr = csr[pmpaddr0+i]; +// if (cfg & PMP_A) { +// any_active=true; +// auto is_tor = bit_sub<3, 2>(cfg) == PMP_TOR; +// auto is_napot = bit_sub<4, 1>(cfg) && bit_sub<3, 2>(cfg_next)!= PMP_TOR; +// if(is_napot) { +// reg_t mask = bit_sub<3, 1>(cfg)?~( pmpaddr & ~(pmpaddr + 1)): 0x3fffffff; +// auto mpmpaddr = pmpaddr & mask; +// if((lower_addr&mask) == mpmpaddr && (upper_addr&mask)==mpmpaddr) +// return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || +// (type == access_type::READ && (cfg & PMP_R)) || +// (type == access_type::WRITE && (cfg & PMP_W)) || +// (type == access_type::FETCH && (cfg & PMP_X)); +// } else if(is_tor) { +// if(lower_addr>=tor_base && upper_addr<=pmpaddr) +// return (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || +// (type == access_type::READ && (cfg & PMP_R)) || +// (type == access_type::WRITE && (cfg & PMP_W)) || +// (type == access_type::FETCH && (cfg & PMP_X)); +// } +// } +// tor_base = pmpaddr; +// } return !any_active || this->reg.PRIV == PRIV_M; } From 7452c5df431cd99a316bd8c89c5d378f29239fba Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 11 Nov 2021 12:16:35 +0100 Subject: [PATCH 36/37] add TGC_D_XRB_NN definition --- gen_input/TGC_D_XRB_NN.core_desc | 133 +++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 gen_input/TGC_D_XRB_NN.core_desc diff --git a/gen_input/TGC_D_XRB_NN.core_desc b/gen_input/TGC_D_XRB_NN.core_desc new file mode 100644 index 0000000..b014856 --- /dev/null +++ b/gen_input/TGC_D_XRB_NN.core_desc @@ -0,0 +1,133 @@ +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_NN extends RISCVBase { + + instructions { + + // signed saturate with pre-shift + SSAT { + // instruction format: R-type + // opcode space: custom-1 (inst[6:2] = 01010) + // opcode = 0b0101011, func3 = 0b000, func7 = + encoding: sat_bit_pos[6:0] :: rs2[4:0] :: rs1[4:0] :: 0b000 :: rd[4:0] :: 0b0101011; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}, {name(sat_bit_pos)}"; + behavior: { + signed val_s = (signed)X[rs1]; + unsigned pre_shift = (unsigned)X[rs2]; + unsigned sat_limit; + signed upper_limit; + signed lower_limit; + + if((rd != 0) && (sat_bit_pos > 0) && (sat_bit_pos <= 32) && (pre_shift < 32)) { + sat_limit = (unsigned)(1 << (sat_bit_pos - 1)); + upper_limit = (signed)sat_limit - 1; + lower_limit = (signed)sat_limit * (-1); + + // important: arithmetical shift right + val_s = val_s >> pre_shift; + X[rd] = (val_s > upper_limit) ? (upper_limit) : ( (val_s < lower_limit) ? (lower_limit) : (val_s) ); + } + } + } + + // custom packed dot product with accumulation (4x8bit) + PDOT8 { + // instruction format: R-type + // opcode space: custom-1 (inst[6:2] = 01010) + // opcode = 0b0101011, func3 = 0b001, func7 = 0b0000000 + encoding: 0b0000000 :: rs2[4:0] :: rs1[4:0] :: 0b001 :: rd[4:0] :: 0b0101011; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; + behavior: { + signed<8> op1_0 = (signed<8>)X[rs1][ 7: 0]; + signed<8> op1_1 = (signed<8>)X[rs1][15: 8]; + signed<8> op1_2 = (signed<8>)X[rs1][23:16]; + signed<8> op1_3 = (signed<8>)X[rs1][31:24]; + + signed<8> op2_0 = (signed<8>)X[rs2][ 7: 0]; + signed<8> op2_1 = (signed<8>)X[rs2][15: 8]; + signed<8> op2_2 = (signed<8>)X[rs2][23:16]; + signed<8> op2_3 = (signed<8>)X[rs2][31:24]; + + signed op3 = (signed)X[rd]; + + signed<16> mul0 = op1_0 * op2_0; + signed<16> mul1 = op1_1 * op2_1; + signed<16> mul2 = op1_2 * op2_2; + signed<16> mul3 = op1_3 * op2_3; + + signed<19> sum_tmp = mul0 + mul1 + mul2 + mul3; + + signed<33> result = op3 + sum_tmp; + + if(rd != 0) X[rd] = result[31:0]; + } + } + + // standard signed multiply accumulate with 32 bit operands and 32 bit result + MAC { + // instruction format: R-type + // opcode space: custom-1 (inst[6:2] = 01010) + // opcode = 0b0101011, func3 = 0b010, func7 = 0b0000000 + encoding: 0b0000000 :: rs2[4:0] :: rs1[4:0] :: 0b010 :: rd[4:0] :: 0b0101011; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; + behavior: { + signed<65> result = (signed)X[rs1] * (signed)X[rs2] + (signed)X[rd]; + if(rd != 0) X[rd] = result[31:0]; + } + } + + + // WARNING: The following two HW loop instructions are not fully specified or implemented. The idea is to design the HW loops identical to the RI5CY core (current naming: CV32E40P) + // See "Short Hardware Loop Setup Instructions" from RI5CY specification document from April 2019, revision 4.0: https://www.pulp-platform.org/docs/ri5cy_user_manual.pdf -> page 38, chapter 14.2 + // Specific CSRs are introduced to support the HW loops (see page 17, chapter 7). + + // lp.setup HW loop (Short Hardware Loop Setup Instruction) + LOOP { + // instruction format: I-type + // opcode space: custom-3 (inst[6:2] = 11110) + // opcode = 0b1111011, func3 = 0b100 + // uimmL[11:0] src1 100 0000 L 111 1011 -> lp.setup L,rs1, uimmL + encoding: imm[11:0] :: rs1[4:0] :: 0b100 :: 0b0000 :: L[0:0] :: 0b1111011; + args_disass:"{name(L)}, {name(rs1)}, {imm}"; + behavior: { + // L: loop level (two loop levels would be sufficient); L=0 has higher priority and is considered as the inner loop. + /* + lpstart[L] = PC + 4; + lpend[L] = PC + ((unsigned<12>)imm << 1); + lpcount[L] = rs1; + */ + } + } + + // lp.setupi HW loop (Short Hardware Loop Setup Instruction with immediate value for loop count) + LOOPI { + // instruction format: I-type + // opcode space: custom-3 (inst[6:2] = 11110) + // opcode = 0b1111011, func3 = 0b101 + // uimmL[11:0] uimmS[4:0] 101 0000 L 111 1011 -> lp.setupi L, uimmS, uimmL + encoding: imm2[11:0] :: imm1[4:0] :: 0b101 :: 0b0000 :: L[0:0] :: 0b1111011; + args_disass:"{name(L)}, {imm1}, {imm2}"; + behavior: { + // L: loop level (two loop levels would be sufficient); L=0 has higher priority and is considered as the inner loop. + /* + lpstart[L] = PC + 4; + lpend[L] = PC + ((unsigned<5>)imm1 << 1); + lpcount[L] = (unsigned<12>)imm2; + */ + } + } + } +} + +Core TGC_D_XRB_NN provides RV32I, Zicsr, Zifencei, RV32M, RV32IC, X_RB_NN { + architectural_state { + XLEN=32; + // definitions for the architecture wrapper + // XL ZYXWVUTSRQPONMLKJIHGFEDCBA + unsigned MISA_VAL = 0b01000000000000000001000100000100; + unsigned MARCHID_VAL = 0x80000004; + } +} From d31b4ef5a8dd05827ea7724d13c4e70298720230 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 11 Nov 2021 12:58:57 +0100 Subject: [PATCH 37/37] fix MISA val --- gen_input/TGC_D_XRB_NN.core_desc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen_input/TGC_D_XRB_NN.core_desc b/gen_input/TGC_D_XRB_NN.core_desc index b014856..bec4c2f 100644 --- a/gen_input/TGC_D_XRB_NN.core_desc +++ b/gen_input/TGC_D_XRB_NN.core_desc @@ -127,7 +127,7 @@ Core TGC_D_XRB_NN provides RV32I, Zicsr, Zifencei, RV32M, RV32IC, X_RB_NN { XLEN=32; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - unsigned MISA_VAL = 0b01000000000000000001000100000100; + unsigned MISA_VAL = 0b01000000100100000011000100000100; unsigned MARCHID_VAL = 0x80000004; } }