From d47375a70ea353ac164b0323f435ea3a017bee1f Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 13 Nov 2021 12:47:23 +0100 Subject: [PATCH 01/41] fix ebreak CSR update --- incl/iss/arch/riscv_hart_m_p.h | 2 +- incl/iss/arch/riscv_hart_msu_vp.h | 22 +++++++++++++++++++++- incl/iss/arch/riscv_hart_mu_p.h | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 4a7046a..f9b4784 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -1015,7 +1015,7 @@ 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] = 0; + csr[mtval] = addr; break; case 4: case 6: diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index aa88e6d..efbe605 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -1276,7 +1276,27 @@ template uint64_t riscv_hart_msu_vp::enter_trap(uint64_t f * 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)] = addr; + break; + case 4: + case 6: + case 7: + csr[utval | (new_priv << 8)] = fault_data; + break; + default: + csr[utval | (new_priv << 8)] = 0; + } fault_data = 0; } else { if (cur_priv != PRIV_M && ((csr[mideleg] >> cause) & 0x1) != 0) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 2444cd7..f48a28e 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -1294,7 +1294,7 @@ template uint64_t riscv_hart_mu_p:: //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; + csr[utval | (new_priv << 8)] = addr; break; case 4: case 6: From 965929d1eb29167f1e7f5a03791d9ffc8d8be423 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 15 Nov 2021 09:30:16 +0100 Subject: [PATCH 02/41] remove descriptions --- gen_input/TGC_B.core_desc | 14 ---- gen_input/TGC_D.core_desc | 13 --- gen_input/TGC_D_XRB_MAC.core_desc | 73 ---------------- gen_input/TGC_D_XRB_NN.core_desc | 133 ------------------------------ 4 files changed, 233 deletions(-) delete mode 100644 gen_input/TGC_B.core_desc delete mode 100644 gen_input/TGC_D.core_desc delete mode 100644 gen_input/TGC_D_XRB_MAC.core_desc delete mode 100644 gen_input/TGC_D_XRB_NN.core_desc diff --git a/gen_input/TGC_B.core_desc b/gen_input/TGC_B.core_desc deleted file mode 100644 index 3686002..0000000 --- a/gen_input/TGC_B.core_desc +++ /dev/null @@ -1,14 +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, Zicsr, Zifencei { - architectural_state { - XLEN=32; - // definitions for the architecture wrapper - // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - unsigned MISA_VAL = 0b01000000000000000000000100000000; - unsigned MARCHID_VAL = 0x80000002; - } -} - diff --git a/gen_input/TGC_D.core_desc b/gen_input/TGC_D.core_desc deleted file mode 100644 index c4d9c54..0000000 --- a/gen_input/TGC_D.core_desc +++ /dev/null @@ -1,13 +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_D provides RV32I, Zicsr, Zifencei, RV32M, RV32IC { - architectural_state { - XLEN=32; - // definitions for the architecture wrapper - // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - unsigned MISA_VAL = 0b01000000000100000011000100000100; - unsigned MARCHID_VAL = 0x80000004; - } -} diff --git a/gen_input/TGC_D_XRB_MAC.core_desc b/gen_input/TGC_D_XRB_MAC.core_desc deleted file mode 100644 index 972b111..0000000 --- a/gen_input/TGC_D_XRB_MAC.core_desc +++ /dev/null @@ -1,73 +0,0 @@ -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, Zicsr, Zifencei, RV32M, RV32IC, X_RB_MAC { - architectural_state { - XLEN=32; - // definitions for the architecture wrapper - // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - unsigned MISA_VAL = 0b01000000000000000001000100000100; - unsigned MARCHID_VAL = 0x80000004; - } -} diff --git a/gen_input/TGC_D_XRB_NN.core_desc b/gen_input/TGC_D_XRB_NN.core_desc deleted file mode 100644 index bec4c2f..0000000 --- a/gen_input/TGC_D_XRB_NN.core_desc +++ /dev/null @@ -1,133 +0,0 @@ -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 = 0b01000000100100000011000100000100; - unsigned MARCHID_VAL = 0x80000004; - } -} From 309758b9941b849807d8445554f1c23985f51b32 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 17 Nov 2021 07:59:02 +0100 Subject: [PATCH 03/41] fix clic_cfg access scheme --- incl/iss/arch/riscv_hart_mu_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index f48a28e..353dfd8 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -1222,7 +1222,7 @@ template iss::status riscv_hart_mu_p::write_clic(uint64_t addr, unsigned length, const uint8_t *const data) { if(addr==clic_base_addr) { // cliccfg clic_cfg_reg = *data; - clic_cfg_reg&= 0x7f; + clic_cfg_reg&= 0x7e; // } else if(addr>=(clic_base_addr+4) && (addr+length)<=(clic_base_addr+4)){ // clicinfo // write_uint32(addr, clic_info_reg, data, length); } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0xC0)){ // clicinttrig From 974d10338187adbce2dc82041d13676a17f32108 Mon Sep 17 00:00:00 2001 From: Maribel Date: Mon, 22 Nov 2021 10:49:29 +0100 Subject: [PATCH 04/41] fix pmpcfg register write --- incl/iss/arch/riscv_hart_mu_p.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 353dfd8..2e22d63 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -330,6 +330,7 @@ protected: 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); + iss::status write_pmpcfg_reg(unsigned addr, reg_t val); reg_t mhartid_reg{0x0}; std::functionmem_read_cb; @@ -425,7 +426,7 @@ riscv_hart_mu_p::riscv_hart_mu_p() } for(size_t i=pmpcfg0; i<=pmpcfg3; ++i){ csr_rd_cb[i] = &this_class::read_csr_reg; - csr_wr_cb[i] = &this_class::write_csr_reg; + csr_wr_cb[i] = &this_class::write_pmpcfg_reg; } } if(FEAT & FEAT_EXT_N){ @@ -544,6 +545,12 @@ template std::pair riscv_hart_m throw std::runtime_error("memory load file not found"); } +template +inline iss::status riscv_hart_mu_p::write_pmpcfg_reg(unsigned addr, reg_t val) { + csr[addr] = val & 0x9f9f9f9f; + return iss::Ok; +} + template bool riscv_hart_mu_p::pmp_check(const access_type type, const uint64_t addr, const unsigned len) { constexpr auto PMP_SHIFT=2U; constexpr auto PMP_R = 0x1U; From 86da31033cecc1496f23c853e566573dbca3971f Mon Sep 17 00:00:00 2001 From: Maribel Date: Mon, 22 Nov 2021 15:15:47 +0100 Subject: [PATCH 05/41] correct size usage in pmp addr checks --- incl/iss/arch/riscv_hart_mu_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 2e22d63..2697afb 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -581,7 +581,7 @@ template bool riscv_hart_mu_p::pmp_ 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 tor_match = base <= (cur_addr+len-1) && cur_addr < tor; auto match = is_tor ? tor_match : napot_match; any_match |= match; all_match &= match; From 6f8595759e26ac532de6dd7eb6e7d27e8bdb4587 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 25 Nov 2021 19:59:50 +0100 Subject: [PATCH 06/41] make tgc-sim include all available ISS --- CMakeLists.txt | 16 ++++++++++------ src/main.cpp | 24 +++++++++++++++++++++++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7577443..e0fd2c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,15 +28,15 @@ endif() add_subdirectory(softfloat) # library files -FILE(GLOB TGC_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/src/iss/*.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp -) +FILE(GLOB TGC_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/iss/*.cpp) +FILE(GLOB TGC_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp) + set(LIB_SOURCES src/vm/fp_functions.cpp src/plugin/instruction_count.cpp src/plugin/cycle_estimate.cpp ${TGC_SOURCES} + ${TGC_VM_SOURCES} ) if(WITH_LLVM) @@ -105,8 +105,12 @@ project(tgc-sim) find_package(Boost COMPONENTS program_options thread REQUIRED) add_executable(${PROJECT_NAME} src/main.cpp) -# This sets the include directory for the reference project. This is the -I flag in gcc. -target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) +foreach(F IN LISTS TGC_SOURCES) + string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F}) + string(TOUPPER ${CORE_NAME_LC} CORE_NAME) + target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) +endforeach() + if(WITH_LLVM) target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_LLVM) target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs}) diff --git a/src/main.cpp b/src/main.cpp index 358d4a1..ee978e3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,6 +54,16 @@ using tgc_d_plat_type = iss::arch::riscv_hart_mu_p; #endif +#ifdef CORE_TGC_D_XRB_NN +#include "iss/arch/riscv_hart_mu_p.h" +#include "iss/arch/tgc_d_xrb_nn.h" +using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p; +#endif +#ifdef CORE_TGC_E +#include "iss/arch/riscv_hart_mu_p.h" +#include "iss/arch/tgc_e.h" +using tgc_e_plat_type = iss::arch::riscv_hart_mu_p; +#endif #ifdef WITH_LLVM #include #endif @@ -153,9 +163,21 @@ 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_NN + if (isa_opt == "tgc_d_xrb_nn") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#endif +#ifdef CORE_TGC_E + if (isa_opt == "tgc_e") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else #endif { - LOG(ERR) << "Illegal argument value for '--isa': " << clim["isa"].as() << std::endl; + LOG(ERR) << "Illegal argument value for '--isa': " << isa_opt << std::endl; return 127; } if (clim.count("plugin")) { From 07d5af1ddef14b4d7a17db376f944dddb341184f Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 26 Nov 2021 17:56:40 +0100 Subject: [PATCH 07/41] fix stand-alone ISS compilation to include all generated cores --- CMakeLists.txt | 14 +++++--------- gen_input/templates/CORENAME_cyles.txt.gtl | 4 ++-- src/sysc/core_complex.cpp | 10 +++++++++- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0fd2c9..aec662a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,15 +146,11 @@ if(SystemC_FOUND) add_library(${PROJECT_NAME} src/sysc/core_complex.cpp) target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/incl/iss/arch/tgc_b.h) - target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_TGC_B) - endif() - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/incl/iss/arch/tgc_c.h) - target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_TGC_C) - endif() - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/incl/iss/arch/tgc_d.h) - target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_TGC_D) - endif() + foreach(F IN LISTS TGC_SOURCES) + string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F}) + string(TOUPPER ${CORE_NAME_LC} CORE_NAME) + target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) + endforeach() target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc scc) if(WITH_LLVM) target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs}) diff --git a/gen_input/templates/CORENAME_cyles.txt.gtl b/gen_input/templates/CORENAME_cyles.txt.gtl index 3a1ad8e..6e8bbf7 100644 --- a/gen_input/templates/CORENAME_cyles.txt.gtl +++ b/gen_input/templates/CORENAME_cyles.txt.gtl @@ -1,9 +1,9 @@ -{ +{ "${coreDef.name}" : [<%instructions.eachWithIndex{instr,index -> %>${index==0?"":","} { "name" : "${instr.name}", "size" : ${instr.length}, - "delay" : ${generator.hasAttribute(instr.instruction, com.minres.coredsl.coreDsl.InstrAttribute.COND)?[1,1]:1} + "delay" : ${instr.isConditional?"[1,1]":"1"} }<%}%> ] } \ No newline at end of file diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 268c9e8..ed21bb8 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -57,6 +57,11 @@ using tgc_d_plat_type = iss::arch::riscv_hart_mu_p; #endif +#ifdef CORE_TGC_D_XRB_NN +#include "iss/arch/riscv_hart_mu_p.h" +#include "iss/arch/tgc_d_xrb_nn.h" +using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p; +#endif #include #include #include @@ -303,8 +308,11 @@ public: #ifdef CORE_TGC_D CREATE_CORE(tgc_d) #endif -#ifdef CORE_TGC_D_XRB_MACD +#ifdef CORE_TGC_D_XRB_MAC CREATE_CORE(tgc_d_xrb_mac) +#endif +#ifdef CORE_TGC_D_XRB_NN + CREATE_CORE(tgc_d_xrb_nn) #endif { LOG(ERR) << "Illegal argument value for core type: " << type << std::endl; From dd4c19a15c93b91d6fb22ebae30c6c097fa7a7c5 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 1 Dec 2021 12:56:36 +0100 Subject: [PATCH 08/41] add option to configure number of irq --- incl/iss/arch/riscv_hart_m_p.h | 7 +++++-- incl/iss/arch/riscv_hart_mu_p.h | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index f9b4784..538071d 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -218,6 +218,9 @@ public: csr[addr & csr.page_addr_mask] = val; } + void set_irq_num(unsigned i) { + mcause_max_irq=1< iss::status riscv_hart_m_p } 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 + csr[mcause] = val & ((1UL<<(traits::XLEN-1))| (mcause_max_irq-1)); return iss::Ok; } @@ -1029,7 +1032,7 @@ template uint64_t riscv_hart_m_p::e csr[mepc] = this->reg.NEXT_PC & get_pc_mask(); // store next address if interrupt this->reg.pending_trap = 0; } - csr[mcause] = (trap_id << 31) + cause; + csr[mcause] = (trap_id << (traits::XLEN-1)) + cause; // update mstatus // xPP field of mstatus is written with the active privilege mode at the time // of the trap; the x PIE field of mstatus diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 2697afb..7ff8eb3 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -233,6 +233,9 @@ public: csr[addr & csr.page_addr_mask] = val; } + void set_irq_num(unsigned i) { + mcause_max_irq=1< iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_cause(unsigned addr, reg_t val) { - csr[addr] = val & ((1UL<<(traits::XLEN-1))|(mcause_max_irq-1)); //TODO: make exception code size configurable + csr[addr] = val & ((1UL<<(traits::XLEN-1))|(mcause_max_irq-1)); return iss::Ok; } @@ -1319,7 +1322,7 @@ template uint64_t riscv_hart_mu_p:: this->reg.pending_trap = 0; } size_t adr = ucause | (new_priv << 8); - csr[adr] = (trap_id << 31) + cause; + csr[adr] = (trap_id << (traits::XLEN-1)) + cause; // update mstatus // xPP field of mstatus is written with the active privilege mode at the time // of the trap; the x PIE field of mstatus From 09955be90fba25efaefb3bd7916e4472dd19e9bd Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 5 Dec 2021 08:41:29 +0100 Subject: [PATCH 09/41] update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index cebb65a..d687e5f 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ language.settings.xml /dump.json /src-gen/ /*.yaml +/*.json From 3563ba80d0555916c2986900e8fc4197205126e5 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 12 Jan 2022 07:21:16 +0100 Subject: [PATCH 10/41] add spawn blocks --- CMakeLists.txt | 3 ++- gen_input/templates/CORENAME.h.gtl | 2 +- gen_input/templates/interp/CORENAME.cpp.gtl | 22 +++++++++++++++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aec662a..ac3bf7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ project(dbt-rise-tgc VERSION 1.0.0) include(GNUInstallDirs) find_package(elfio) +find_package(Boost COMPONENTS coroutine) if(WITH_LLVM) if(DEFINED ENV{LLVM_HOME}) @@ -66,7 +67,7 @@ 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) +target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp Boost::coroutine) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive) else() diff --git a/gen_input/templates/CORENAME.h.gtl b/gen_input/templates/CORENAME.h.gtl index 2105569..fa69704 100644 --- a/gen_input/templates/CORENAME.h.gtl +++ b/gen_input/templates/CORENAME.h.gtl @@ -161,7 +161,7 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { inline uint32_t get_last_branch() { return reg.last_branch; } -protected: + #pragma pack(push, 1) struct ${coreDef.name}_regs {<% registers.each { reg -> if(reg.size>0) {%> diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 7cf5c47..26db3d0 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -45,6 +45,8 @@ def nativeTypeSize(int size){ #include #include #include +#include +#include #ifndef FMT_HEADER_ONLY #define FMT_HEADER_ONLY @@ -59,6 +61,7 @@ namespace interp { namespace ${coreDef.name.toLowerCase()} { using namespace iss::arch; using namespace iss::debugger; +using namespace std::placeholders; template class vm_impl : public iss::interp::vm_base { public: @@ -130,6 +133,10 @@ protected: this->core.wait_until(type); } + using yield_t = boost::coroutines2::coroutine::push_type; + using coro_t = boost::coroutines2::coroutine::pull_type; + std::vector spawn_blocks; + template T& pc_assign(T& val){super::ex_info.branch_taken=true; return val;} inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){ @@ -174,7 +181,9 @@ protected: auto sign_mask = 1ULL<<(W-1); return (from & mask) | ((from & sign_mask) ? ~mask : 0); } - +<%functions.each{ it.eachLine { %> + ${it}<%}%> +<%}%> private: /**************************************************************************** * start opcode definitions @@ -196,11 +205,6 @@ private: /* instruction ${idx}: ${instr.name} */ compile_ret_t __${generator.functionName(instr.name)}(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, ${idx}); <%instr.fields.eachLine{%>${it} <%}%>if(this->disass_enabled){ @@ -208,6 +212,9 @@ private: <%instr.disass.eachLine{%>${it} <%}%> } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // 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{ %> @@ -219,6 +226,7 @@ private: <%instr.behavior.eachLine{%>${it} <%}%>} catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx}); // trap check if(*trap_state!=0){ @@ -335,6 +343,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto f = decode_inst(insn); auto old_pc = pc.val; pc = (this->*f)(pc, insn); + this->core.reg.PC = this->core.reg.NEXT_PC; + this->core.reg.trap_state = this->core.reg.pending_trap; } } return pc; From ecc6091d1ea5459f09ba32d85aa4fe9f114f6539 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Wed, 19 Jan 2022 08:01:15 +0100 Subject: [PATCH 11/41] cleans up source code to remove clang compiler warnings --- incl/iss/arch/riscv_hart_m_p.h | 6 +-- incl/iss/arch/riscv_hart_msu_vp.h | 8 ++-- incl/iss/arch/riscv_hart_mu_p.h | 6 +-- src/vm/interp/vm_tgc_c.cpp | 71 ++++++++++++++++++------------- 4 files changed, 51 insertions(+), 40 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 538071d..36d31c9 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -233,11 +233,11 @@ protected: */ const std::string core_type_name() const override { return traits::core_type; } - virtual uint64_t get_pc() { return arch.get_pc(); }; + uint64_t get_pc() override { return arch.get_pc(); }; - virtual uint64_t get_next_pc() { return arch.get_next_pc(); }; + uint64_t get_next_pc() override { return arch.get_next_pc(); }; - virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; }; + void set_curr_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; }; riscv_hart_m_p &arch; }; diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index efbe605..5ac10f1 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -293,16 +293,16 @@ public: std::pair load_file(std::string name, int type = -1) override; - virtual phys_addr_t virt2phys(const iss::addr_t &addr) override; + phys_addr_t virt2phys(const iss::addr_t &addr) override; iss::status read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, const unsigned length, uint8_t *const data) override; iss::status 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) override; - virtual uint64_t enter_trap(uint64_t flags) override { return riscv_hart_msu_vp::enter_trap(flags, fault_data, fault_data); } - virtual uint64_t enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) override; - virtual uint64_t leave_trap(uint64_t flags) override; + uint64_t enter_trap(uint64_t flags) override { return riscv_hart_msu_vp::enter_trap(flags, fault_data, fault_data); } + uint64_t enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) override; + uint64_t leave_trap(uint64_t flags) override; void wait_until(uint64_t flags) override; void disass_output(uint64_t pc, const std::string instr) override { diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 7ff8eb3..99d1803 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -207,9 +207,9 @@ public: iss::status 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) override; - virtual uint64_t enter_trap(uint64_t flags) override { return riscv_hart_mu_p::enter_trap(flags, fault_data, fault_data); } - virtual uint64_t enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) override; - virtual uint64_t leave_trap(uint64_t flags) override; + uint64_t enter_trap(uint64_t flags) override { return riscv_hart_mu_p::enter_trap(flags, fault_data, fault_data); } + uint64_t enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) override; + uint64_t leave_trap(uint64_t flags) override; const reg_t& get_mhartid() const { return mhartid_reg; } void set_mhartid(reg_t mhartid) { mhartid_reg = mhartid; }; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index ad50b5a..a201ec8 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -568,12 +568,13 @@ private: *NEXT_PC = *PC + 4; // execute instruction try { - { - if(*(X+rs1) == *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + if(*(X+rs1) == *(X+rs2)){ + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + }else{ + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } - else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); - } } catch(...){} // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); @@ -614,12 +615,14 @@ private: *NEXT_PC = *PC + 4; // execute instruction try { - { - if(*(X+rs1) != *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + if(*(X+rs1) != *(X+rs2)){ + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } } - else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); - } + else{ + + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);} } catch(...){} // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); @@ -660,12 +663,14 @@ private: *NEXT_PC = *PC + 4; // execute instruction try { - { - if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + 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); } - else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); - } } catch(...){} // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); @@ -706,12 +711,14 @@ private: *NEXT_PC = *PC + 4; // execute instruction try { - { - if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + 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); } - else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); - } } catch(...){} // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); @@ -752,12 +759,14 @@ private: *NEXT_PC = *PC + 4; // execute instruction try { - { - if(*(X+rs1) < *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + if(*(X+rs1) < *(X+rs2)){ + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + } + else{ + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } - else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); - } } catch(...){} // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); @@ -798,12 +807,14 @@ private: *NEXT_PC = *PC + 4; // execute instruction try { - { - if(*(X+rs1) >= *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + if(*(X+rs1) >= *(X+rs2)){ + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + } + else{ + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } - else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); - } } catch(...){} // post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); From afe8905ac9abc4007998bfcaf43686c057bd0631 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 31 Jan 2022 20:06:12 +0100 Subject: [PATCH 12/41] fix else-ambiguity in CoreDSL description --- gen_input/CoreDSL-Instruction-Set-Description | 1 - incl/iss/arch/tgc_c.h | 2 +- src/vm/interp/vm_tgc_c.cpp | 884 ++++++++---------- 3 files changed, 403 insertions(+), 484 deletions(-) delete mode 160000 gen_input/CoreDSL-Instruction-Set-Description diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description deleted file mode 160000 index b005607..0000000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b005607fc30c4467683b6044eaca7eb378061b53 diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index 2efcaf9..975c205 100644 --- a/incl/iss/arch/tgc_c.h +++ b/incl/iss/arch/tgc_c.h @@ -217,7 +217,7 @@ struct tgc_c: public arch_if { inline uint32_t get_last_branch() { return reg.last_branch; } -protected: + #pragma pack(push, 1) struct TGC_C_regs { uint32_t X0 = 0; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index a201ec8..fedca0b 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -39,6 +39,8 @@ #include #include #include +#include +#include #ifndef FMT_HEADER_ONLY #define FMT_HEADER_ONLY @@ -53,6 +55,7 @@ namespace interp { namespace tgc_c { using namespace iss::arch; using namespace iss::debugger; +using namespace std::placeholders; template class vm_impl : public iss::interp::vm_base { public: @@ -124,6 +127,10 @@ protected: this->core.wait_until(type); } + using yield_t = boost::coroutines2::coroutine::push_type; + using coro_t = boost::coroutines2::coroutine::pull_type; + std::vector spawn_blocks; + template T& pc_assign(T& val){super::ex_info.branch_taken=true; return val;} inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){ @@ -368,11 +375,6 @@ private: /* instruction 0: LUI */ compile_ret_t __lui(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, 0); uint8_t rd = ((bit_sub<7,5>(instr))); uint32_t imm = ((bit_sub<12,20>(instr) << 12)); @@ -384,6 +386,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -392,6 +397,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)imm; } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 0); // trap check if(*trap_state!=0){ @@ -408,11 +414,6 @@ private: /* instruction 1: AUIPC */ compile_ret_t __auipc(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, 1); uint8_t rd = ((bit_sub<7,5>(instr))); uint32_t imm = ((bit_sub<12,20>(instr) << 12)); @@ -424,6 +425,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -432,6 +436,7 @@ private: if(rd != 0) *(X+rd) = *PC + (int32_t)imm; } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 1); // trap check if(*trap_state!=0){ @@ -448,11 +453,6 @@ private: /* instruction 2: JAL */ compile_ret_t __jal(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, 2); uint8_t rd = ((bit_sub<7,5>(instr))); uint32_t imm = ((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); @@ -464,6 +464,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -480,6 +483,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); // trap check if(*trap_state!=0){ @@ -496,11 +500,6 @@ private: /* instruction 3: JALR */ compile_ret_t __jalr(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, 3); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -513,6 +512,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -530,6 +532,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3); // trap check if(*trap_state!=0){ @@ -546,11 +549,6 @@ private: /* instruction 4: BEQ */ compile_ret_t __beq(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, 4); uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -563,20 +561,25 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction try { - if(*(X+rs1) == *(X+rs2)){ - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - }else{ + { + 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 + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); // trap check if(*trap_state!=0){ @@ -593,11 +596,6 @@ private: /* instruction 5: BNE */ compile_ret_t __bne(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, 5); uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -610,21 +608,25 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction try { - if(*(X+rs1) != *(X+rs2)){ - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } + { + if(*(X+rs1) != *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } - else{ - - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);} + else { + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); + } + } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); // trap check if(*trap_state!=0){ @@ -641,11 +643,6 @@ private: /* instruction 6: BLT */ compile_ret_t __blt(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, 6); uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -658,21 +655,25 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction try { - if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)){ - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } + { + if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } - else{ + else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } + } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); // trap check if(*trap_state!=0){ @@ -689,11 +690,6 @@ private: /* instruction 7: BGE */ compile_ret_t __bge(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, 7); uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -706,21 +702,25 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction try { - if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)){ - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } + { + if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } - else{ + else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } + } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); // trap check if(*trap_state!=0){ @@ -737,11 +737,6 @@ private: /* instruction 8: BLTU */ compile_ret_t __bltu(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, 8); uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -754,21 +749,25 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction try { - if(*(X+rs1) < *(X+rs2)){ - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } + { + if(*(X+rs1) < *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } - else{ + else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } + } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); // trap check if(*trap_state!=0){ @@ -785,11 +784,6 @@ private: /* instruction 9: BGEU */ compile_ret_t __bgeu(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, 9); uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -802,21 +796,25 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction try { - if(*(X+rs1) >= *(X+rs2)){ - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } + { + if(*(X+rs1) >= *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } - else{ + else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); } + } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); // trap check if(*trap_state!=0){ @@ -833,11 +831,6 @@ private: /* instruction 10: LB */ compile_ret_t __lb(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, 10); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -850,6 +843,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -861,6 +857,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10); // trap check if(*trap_state!=0){ @@ -877,11 +874,6 @@ private: /* instruction 11: LH */ compile_ret_t __lh(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, 11); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -894,6 +886,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -906,6 +901,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11); // trap check if(*trap_state!=0){ @@ -922,11 +918,6 @@ private: /* instruction 12: LW */ compile_ret_t __lw(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, 12); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -939,6 +930,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -951,6 +945,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12); // trap check if(*trap_state!=0){ @@ -967,11 +962,6 @@ private: /* instruction 13: LBU */ compile_ret_t __lbu(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, 13); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -984,6 +974,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -995,6 +988,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13); // trap check if(*trap_state!=0){ @@ -1011,11 +1005,6 @@ private: /* instruction 14: LHU */ compile_ret_t __lhu(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, 14); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1028,6 +1017,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1040,6 +1032,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14); // trap check if(*trap_state!=0){ @@ -1056,11 +1049,6 @@ private: /* instruction 15: SB */ compile_ret_t __sb(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, 15); uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1073,6 +1061,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1081,6 +1072,7 @@ private: writeSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2)); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); // trap check if(*trap_state!=0){ @@ -1097,11 +1089,6 @@ private: /* instruction 16: SH */ compile_ret_t __sh(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, 16); uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1114,6 +1101,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1125,6 +1115,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16); // trap check if(*trap_state!=0){ @@ -1141,11 +1132,6 @@ private: /* instruction 17: SW */ compile_ret_t __sw(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, 17); uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1158,6 +1144,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1169,6 +1158,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17); // trap check if(*trap_state!=0){ @@ -1185,11 +1175,6 @@ private: /* instruction 18: ADDI */ compile_ret_t __addi(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, 18); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1202,6 +1187,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1210,6 +1198,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); // trap check if(*trap_state!=0){ @@ -1226,11 +1215,6 @@ private: /* instruction 19: SLTI */ compile_ret_t __slti(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, 19); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1243,6 +1227,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1251,6 +1238,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); // trap check if(*trap_state!=0){ @@ -1267,11 +1255,6 @@ private: /* instruction 20: SLTIU */ compile_ret_t __sltiu(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, 20); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1284,6 +1267,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1292,6 +1278,7 @@ private: if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 20); // trap check if(*trap_state!=0){ @@ -1308,11 +1295,6 @@ private: /* instruction 21: XORI */ compile_ret_t __xori(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, 21); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1325,6 +1307,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1333,6 +1318,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); // trap check if(*trap_state!=0){ @@ -1349,11 +1335,6 @@ private: /* instruction 22: ORI */ compile_ret_t __ori(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, 22); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1366,6 +1347,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1374,6 +1358,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); // trap check if(*trap_state!=0){ @@ -1390,11 +1375,6 @@ private: /* instruction 23: ANDI */ compile_ret_t __andi(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, 23); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1407,6 +1387,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1415,6 +1398,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); // trap check if(*trap_state!=0){ @@ -1431,11 +1415,6 @@ private: /* instruction 24: SLLI */ compile_ret_t __slli(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, 24); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1448,6 +1427,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1461,6 +1443,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24); // trap check if(*trap_state!=0){ @@ -1477,11 +1460,6 @@ private: /* instruction 25: SRLI */ compile_ret_t __srli(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, 25); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1494,6 +1472,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1507,6 +1488,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25); // trap check if(*trap_state!=0){ @@ -1523,11 +1505,6 @@ private: /* instruction 26: SRAI */ compile_ret_t __srai(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, 26); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1540,6 +1517,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1553,6 +1533,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26); // trap check if(*trap_state!=0){ @@ -1569,11 +1550,6 @@ private: /* instruction 27: ADD */ compile_ret_t __add(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, 27); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1586,6 +1562,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1594,6 +1573,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 27); // trap check if(*trap_state!=0){ @@ -1610,11 +1590,6 @@ private: /* instruction 28: SUB */ compile_ret_t __sub(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, 28); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1627,6 +1602,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1635,6 +1613,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 28); // trap check if(*trap_state!=0){ @@ -1651,11 +1630,6 @@ private: /* instruction 29: SLL */ compile_ret_t __sll(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, 29); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1668,6 +1642,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1676,6 +1653,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 29); // trap check if(*trap_state!=0){ @@ -1692,11 +1670,6 @@ private: /* instruction 30: SLT */ compile_ret_t __slt(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, 30); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1709,6 +1682,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1717,6 +1693,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 30); // trap check if(*trap_state!=0){ @@ -1733,11 +1710,6 @@ private: /* instruction 31: SLTU */ compile_ret_t __sltu(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, 31); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1750,6 +1722,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1758,6 +1733,7 @@ private: if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 31); // trap check if(*trap_state!=0){ @@ -1774,11 +1750,6 @@ private: /* instruction 32: XOR */ compile_ret_t __xor(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, 32); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1791,6 +1762,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1799,6 +1773,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 32); // trap check if(*trap_state!=0){ @@ -1815,11 +1790,6 @@ private: /* instruction 33: SRL */ compile_ret_t __srl(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, 33); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1832,6 +1802,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1840,6 +1813,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 33); // trap check if(*trap_state!=0){ @@ -1856,11 +1830,6 @@ private: /* instruction 34: SRA */ compile_ret_t __sra(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, 34); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1873,6 +1842,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1881,6 +1853,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 34); // trap check if(*trap_state!=0){ @@ -1897,11 +1870,6 @@ private: /* instruction 35: OR */ compile_ret_t __or(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, 35); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1914,6 +1882,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1922,6 +1893,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 35); // trap check if(*trap_state!=0){ @@ -1938,11 +1910,6 @@ private: /* instruction 36: AND */ compile_ret_t __and(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, 36); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1955,6 +1922,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -1963,6 +1933,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 36); // trap check if(*trap_state!=0){ @@ -1979,11 +1950,6 @@ private: /* instruction 37: FENCE */ compile_ret_t __fence(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, 37); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1998,6 +1964,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction @@ -2005,6 +1974,7 @@ private: writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 37); // trap check if(*trap_state!=0){ @@ -2021,17 +1991,15 @@ private: /* instruction 38: ECALL */ compile_ret_t __ecall(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, 38); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "ecall"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction @@ -2039,6 +2007,7 @@ private: raise(0, 11); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 38); // trap check if(*trap_state!=0){ @@ -2055,17 +2024,15 @@ private: /* instruction 39: EBREAK */ compile_ret_t __ebreak(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, 39); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "ebreak"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction @@ -2073,6 +2040,7 @@ private: raise(0, 3); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 39); // trap check if(*trap_state!=0){ @@ -2089,17 +2057,15 @@ private: /* instruction 40: URET */ compile_ret_t __uret(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, 40); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "uret"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction @@ -2107,6 +2073,7 @@ private: leave(0); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 40); // trap check if(*trap_state!=0){ @@ -2123,17 +2090,15 @@ private: /* instruction 41: SRET */ compile_ret_t __sret(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, 41); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "sret"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction @@ -2141,6 +2106,7 @@ private: leave(1); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 41); // trap check if(*trap_state!=0){ @@ -2157,17 +2123,15 @@ private: /* instruction 42: MRET */ compile_ret_t __mret(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, 42); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "mret"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction @@ -2175,6 +2139,7 @@ private: leave(3); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 42); // trap check if(*trap_state!=0){ @@ -2191,17 +2156,15 @@ private: /* instruction 43: WFI */ compile_ret_t __wfi(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, 43); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "wfi"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction @@ -2209,6 +2172,7 @@ private: wait(1); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 43); // trap check if(*trap_state!=0){ @@ -2225,17 +2189,15 @@ private: /* 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]); - *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, 44); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "dret"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* PRIV = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PRIV]); @@ -2253,6 +2215,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); // trap check if(*trap_state!=0){ @@ -2269,11 +2232,6 @@ private: /* 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))); @@ -2286,6 +2244,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2304,6 +2265,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); // trap check if(*trap_state!=0){ @@ -2320,11 +2282,6 @@ private: /* 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]); - 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, 46); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2337,6 +2294,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2350,6 +2310,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); // trap check if(*trap_state!=0){ @@ -2366,11 +2327,6 @@ private: /* 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]); - 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, 47); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2383,6 +2339,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2396,6 +2355,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); // trap check if(*trap_state!=0){ @@ -2412,11 +2372,6 @@ private: /* 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]); - 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, 48); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2429,6 +2384,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2441,6 +2399,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); // trap check if(*trap_state!=0){ @@ -2457,11 +2416,6 @@ private: /* 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]); - 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, 49); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2474,6 +2428,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2486,6 +2443,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); // trap check if(*trap_state!=0){ @@ -2502,11 +2460,6 @@ private: /* 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]); - 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, 50); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2519,6 +2472,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2531,6 +2487,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); // trap check if(*trap_state!=0){ @@ -2547,11 +2504,6 @@ private: /* 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]); - 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))); @@ -2564,6 +2516,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction @@ -2571,6 +2526,7 @@ private: writeSpace2(traits::FENCE, traits::fencei, imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); // trap check if(*trap_state!=0){ @@ -2587,11 +2543,6 @@ private: /* 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]); - 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, 52); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2604,6 +2555,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2617,6 +2571,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); // trap check if(*trap_state!=0){ @@ -2633,11 +2588,6 @@ private: /* 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]); - 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, 53); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2650,6 +2600,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2663,6 +2616,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); // trap check if(*trap_state!=0){ @@ -2679,11 +2633,6 @@ private: /* 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]); - 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, 54); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2696,6 +2645,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2709,6 +2661,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); // trap check if(*trap_state!=0){ @@ -2725,11 +2678,6 @@ private: /* 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]); - 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, 55); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2742,6 +2690,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2755,6 +2706,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); // trap check if(*trap_state!=0){ @@ -2771,11 +2723,6 @@ private: /* 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]); - 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, 56); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2788,6 +2735,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2805,6 +2755,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); // trap check if(*trap_state!=0){ @@ -2821,11 +2772,6 @@ private: /* 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]); - 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, 57); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2838,6 +2784,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2851,6 +2800,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); // trap check if(*trap_state!=0){ @@ -2867,11 +2817,6 @@ private: /* 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]); - 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, 58); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2884,6 +2829,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2901,6 +2849,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); // trap check if(*trap_state!=0){ @@ -2917,11 +2866,6 @@ private: /* 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]); - 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, 59); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2934,6 +2878,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; @@ -2947,6 +2894,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); // trap check if(*trap_state!=0){ @@ -2963,11 +2911,6 @@ private: /* 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]); - 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, 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)); @@ -2979,6 +2922,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -2988,6 +2934,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); // trap check if(*trap_state!=0){ @@ -3004,11 +2951,6 @@ private: /* 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]); - 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, 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)); @@ -3021,6 +2963,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3032,6 +2977,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); // trap check if(*trap_state!=0){ @@ -3048,11 +2994,6 @@ private: /* 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]); - 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, 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)); @@ -3065,6 +3006,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3076,6 +3020,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); // trap check if(*trap_state!=0){ @@ -3092,11 +3037,6 @@ private: /* 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]); - 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, 63); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rs1 = ((bit_sub<7,5>(instr))); @@ -3108,6 +3048,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3116,6 +3059,7 @@ private: *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); // trap check if(*trap_state!=0){ @@ -3132,11 +3076,6 @@ private: /* 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]); - 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, 64); uint8_t nzimm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); if(this->disass_enabled){ @@ -3144,6 +3083,9 @@ private: this->core.disass_output(pc.val, "cnop"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction @@ -3152,6 +3094,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); // trap check if(*trap_state!=0){ @@ -3168,11 +3111,6 @@ private: /* 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]); - 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, 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){ @@ -3183,6 +3121,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3194,6 +3135,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); // trap check if(*trap_state!=0){ @@ -3210,11 +3152,6 @@ private: /* 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]); - 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, 66); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -3226,6 +3163,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3236,6 +3176,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); // trap check if(*trap_state!=0){ @@ -3252,11 +3193,6 @@ private: /* 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]); - 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); uint32_t imm = ((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -3268,6 +3204,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3279,6 +3218,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); // trap check if(*trap_state!=0){ @@ -3295,11 +3235,6 @@ private: /* 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]); - 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); 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){ @@ -3310,6 +3245,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3319,6 +3257,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); // trap check if(*trap_state!=0){ @@ -3335,11 +3274,6 @@ private: /* 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]); - *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 rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3347,6 +3281,9 @@ private: this->core.disass_output(pc.val, "__reserved_clui"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction @@ -3354,6 +3291,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); // trap check if(*trap_state!=0){ @@ -3370,11 +3308,6 @@ private: /* 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))); @@ -3386,6 +3319,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3397,6 +3333,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); // trap check if(*trap_state!=0){ @@ -3413,11 +3350,6 @@ private: /* 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]); - 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, 71); uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -3429,6 +3361,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3444,6 +3379,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); // trap check if(*trap_state!=0){ @@ -3460,11 +3396,6 @@ private: /* 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]); - 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, 72); uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -3476,6 +3407,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3487,6 +3421,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); // trap check if(*trap_state!=0){ @@ -3503,11 +3438,6 @@ private: /* 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]); - 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, 73); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); @@ -3519,6 +3449,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3530,6 +3463,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); // trap check if(*trap_state!=0){ @@ -3546,11 +3480,6 @@ private: /* 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]); - 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, 74); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); @@ -3562,6 +3491,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3573,6 +3505,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); // trap check if(*trap_state!=0){ @@ -3589,11 +3522,6 @@ private: /* 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]); - 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, 75); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); @@ -3605,6 +3533,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3616,6 +3547,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); // trap check if(*trap_state!=0){ @@ -3632,11 +3564,6 @@ private: /* 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]); - 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, 76); uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); @@ -3648,6 +3575,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3659,6 +3589,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); // trap check if(*trap_state!=0){ @@ -3675,11 +3606,6 @@ private: /* 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]); - 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, 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){ @@ -3690,6 +3616,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction @@ -3697,6 +3626,7 @@ private: pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); // trap check if(*trap_state!=0){ @@ -3713,11 +3643,6 @@ private: /* 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]); - 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, 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))); @@ -3729,6 +3654,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3737,6 +3665,7 @@ private: if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); // trap check if(*trap_state!=0){ @@ -3753,11 +3682,6 @@ private: /* 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]); - 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, 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))); @@ -3769,6 +3693,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3777,6 +3704,7 @@ private: if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); // trap check if(*trap_state!=0){ @@ -3793,11 +3721,6 @@ private: /* 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]); - 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, 80); uint8_t nzuimm = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,5>(instr))); @@ -3809,6 +3732,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3817,6 +3743,7 @@ private: if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); // trap check if(*trap_state!=0){ @@ -3833,11 +3760,6 @@ private: /* 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]); - 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, 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))); @@ -3849,6 +3771,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3861,6 +3786,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); // trap check if(*trap_state!=0){ @@ -3877,11 +3803,6 @@ private: /* 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]); - 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); uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -3893,6 +3814,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3901,6 +3825,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); // trap check if(*trap_state!=0){ @@ -3917,11 +3842,6 @@ private: /* 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]); - 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); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -3932,6 +3852,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -3941,6 +3864,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); // trap check if(*trap_state!=0){ @@ -3957,17 +3881,15 @@ private: /* 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]); - *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->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "__reserved_cmv"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction @@ -3975,6 +3897,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); // trap check if(*trap_state!=0){ @@ -3991,11 +3914,6 @@ private: /* 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))); @@ -4007,6 +3925,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -4015,6 +3936,7 @@ private: if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); // trap check if(*trap_state!=0){ @@ -4031,11 +3953,6 @@ private: /* 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]); - 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); uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -4046,6 +3963,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -4058,6 +3978,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); // trap check if(*trap_state!=0){ @@ -4074,17 +3995,15 @@ private: /* 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]); - *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->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "cebreak"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction @@ -4092,6 +4011,7 @@ private: raise(0, 3); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); // trap check if(*trap_state!=0){ @@ -4108,11 +4028,6 @@ private: /* 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)); @@ -4124,6 +4039,9 @@ private: this->core.disass_output(pc.val, mnemonic); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; @@ -4135,6 +4053,7 @@ private: } } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 88); // trap check if(*trap_state!=0){ @@ -4151,17 +4070,15 @@ private: /* 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]); - 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, 89); if(this->disass_enabled){ /* generate console output when executing the command */ this->core.disass_output(pc.val, "dii"); } + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction @@ -4169,6 +4086,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff + for(auto& spawn_block:spawn_blocks) spawn_block(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 89); // trap check if(*trap_state!=0){ @@ -4285,6 +4203,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto f = decode_inst(insn); auto old_pc = pc.val; pc = (this->*f)(pc, insn); + this->core.reg.PC = this->core.reg.NEXT_PC; + this->core.reg.trap_state = this->core.reg.pending_trap; } } return pc; From 75789063107b8c125a0b840f248fa17c9fa8b343 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Mon, 31 Jan 2022 21:38:18 +0100 Subject: [PATCH 13/41] adds coverage plugin --- CMakeLists.txt | 2 + incl/iss/plugin/cov.h | 84 +++++++++++++++++++++++++++++++++++++++ src/plugin/cov.cpp | 32 +++++++++++++++ src/sysc/core_complex.cpp | 6 +++ 4 files changed, 124 insertions(+) create mode 100644 incl/iss/plugin/cov.h create mode 100644 src/plugin/cov.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ac3bf7f..8c94083 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ set(LIB_SOURCES src/vm/fp_functions.cpp src/plugin/instruction_count.cpp src/plugin/cycle_estimate.cpp + src/plugin/cov.cpp + ${TGC_SOURCES} ${TGC_VM_SOURCES} ) diff --git a/incl/iss/plugin/cov.h b/incl/iss/plugin/cov.h new file mode 100644 index 0000000..1f0c9bd --- /dev/null +++ b/incl/iss/plugin/cov.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (C) 2017, 2018, MINRES Technologies GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Contributors: + * eyck@minres.com - initial API and implementation + ******************************************************************************/ + +#ifndef _ISS_PLUGIN_COV_H_ +#define _ISS_PLUGIN_COV_H_ + +#include +#include "iss/instrumentation_if.h" +#include +#include +#include + + +namespace iss { +namespace plugin { + +class cov : public iss::vm_plugin { + struct instr_delay { + std::string instr_name; + size_t size; + size_t not_taken_delay; + size_t taken_delay; + }; + +public: + + cov(const cov &) = delete; + + cov(const cov &&) = delete; + + cov(); + + virtual ~cov(); + + cov &operator=(const cov &) = delete; + + cov &operator=(const cov &&) = delete; + + bool registration(const char *const version, vm_if &arch) override; + + sync_type get_sync() override { return POST_SYNC; }; + + void callback(instr_info_t, exec_info const&) override; + +private: + iss::instrumentation_if *instr_if {nullptr}; + int counter {0}; + std::ofstream output; +}; +} +} + +#endif /* _ISS_PLUGIN_COV_H_ */ diff --git a/src/plugin/cov.cpp b/src/plugin/cov.cpp new file mode 100644 index 0000000..46b1d32 --- /dev/null +++ b/src/plugin/cov.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + + +iss::plugin::cov::cov() { + std::cout << "Entering Constructor"<get_instrumentation_if(); + return true; +} +void iss::plugin::cov::callback(instr_info_t iinfo, const exec_info&) { +// if((instr_if->get_next_pc() - instr_if->get_pc() != 4) ||( instr_if->get_next_pc() - instr_if->get_pc() != 2)){ +// std::cout << "jump from " << std::hex << instr_if->get_pc() << " to " << instr_if->get_next_pc()<< " after " << std::dec << counter <<" linear instructions" <get_pc() << std::endl; +} diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index ed21bb8..c89f61f 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -69,6 +69,8 @@ using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p #include #include +#include + // clang-format on #define STR(X) #X @@ -423,6 +425,10 @@ void core_complex::before_end_of_elaboration() { auto *plugin = new iss::plugin::cycle_estimate(filename); cpu->vm->register_plugin(*plugin); plugin_list.push_back(plugin); + } else if (plugin_name == "cov") { + auto *plugin = new iss::plugin::cov(); + cpu->vm->register_plugin(*plugin); + plugin_list.push_back(plugin); } else { std::array a{{filename.c_str()}}; iss::plugin::loader l(plugin_name, {{"initPlugin"}}); From ef2a4df925d621b3e57f5d10e61dbcc90b4e60cc Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 31 Jan 2022 23:40:19 +0100 Subject: [PATCH 14/41] simplify spawn block handling --- gen_input/templates/interp/CORENAME.cpp.gtl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 26db3d0..119c084 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -181,6 +181,15 @@ protected: auto sign_mask = 1ULL<<(W-1); return (from & mask) | ((from & sign_mask) ? ~mask : 0); } + + inline void process_spawn_blocks() { + for(auto it = std::begin(spawn_blocks); it!=std::end(spawn_blocks);) + if(*it){ + (*it)(); + ++it; + } else + spawn_blocks.erase(it); + } <%functions.each{ it.eachLine { %> ${it}<%}%> <%}%> @@ -226,7 +235,7 @@ private: <%instr.behavior.eachLine{%>${it} <%}%>} catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx}); // trap check if(*trap_state!=0){ From 059bd0d371ce3ae2ac28e9f930b251a07e6a167a Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 1 Feb 2022 19:03:45 +0100 Subject: [PATCH 15/41] rework cycle estimation --- gen_input/templates/CORENAME_cyles.txt.gtl | 9 +- incl/iss/plugin/cycle_estimate.h | 5 +- src/plugin/cycle_estimate.cpp | 89 ++++++---- src/vm/interp/vm_tgc_c.cpp | 189 +++++++++++---------- 4 files changed, 161 insertions(+), 131 deletions(-) diff --git a/gen_input/templates/CORENAME_cyles.txt.gtl b/gen_input/templates/CORENAME_cyles.txt.gtl index 6e8bbf7..cef9f6f 100644 --- a/gen_input/templates/CORENAME_cyles.txt.gtl +++ b/gen_input/templates/CORENAME_cyles.txt.gtl @@ -1,9 +1,12 @@ { "${coreDef.name}" : [<%instructions.eachWithIndex{instr,index -> %>${index==0?"":","} { - "name" : "${instr.name}", - "size" : ${instr.length}, - "delay" : ${instr.isConditional?"[1,1]":"1"} + "name" : "${instr.name}", + "size" : ${instr.length}, + "encoding": ${instr.encoding}, + "mask": ${instr.mask}, + "branch": ${instr.modifiesPC}, + "delay" : ${instr.isConditional?"[1,1]":"1"} }<%}%> ] } \ No newline at end of file diff --git a/incl/iss/plugin/cycle_estimate.h b/incl/iss/plugin/cycle_estimate.h index 0685b4a..c2c9666 100644 --- a/incl/iss/plugin/cycle_estimate.h +++ b/incl/iss/plugin/cycle_estimate.h @@ -37,7 +37,6 @@ #include "iss/instrumentation_if.h" #include "iss/vm_plugin.h" -#include #include #include @@ -64,7 +63,7 @@ public: cycle_estimate(const cycle_estimate &&) = delete; - cycle_estimate(std::string config_file_name); + cycle_estimate(std::string const& config_file_name); virtual ~cycle_estimate(); @@ -88,7 +87,7 @@ private: } }; std::unordered_map, uint64_t, pair_hash> blocks; - Json::Value root; + std::string config_file_name; }; } } diff --git a/src/plugin/cycle_estimate.cpp b/src/plugin/cycle_estimate.cpp index 3aa856b..bf642f1 100644 --- a/src/plugin/cycle_estimate.cpp +++ b/src/plugin/cycle_estimate.cpp @@ -36,57 +36,76 @@ #include #include +#include +#include +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" +#include #include -iss::plugin::cycle_estimate::cycle_estimate(std::string config_file_name) +using namespace rapidjson; +using namespace std; + +iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name) : arch_instr(nullptr) +, config_file_name(config_file_name) { - if (config_file_name.length() > 0) { - std::ifstream is(config_file_name); - if (is.is_open()) { - try { - is >> root; - } catch (Json::RuntimeError &e) { - LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what(); - } - } else { - LOG(ERR) << "Could not open input file " << config_file_name; - } - } } iss::plugin::cycle_estimate::~cycle_estimate() { } bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& vm) { - arch_instr = vm.get_arch()->get_instrumentation_if(); - if(!arch_instr) return false; - const std::string core_name = arch_instr->core_type_name(); - Json::Value &val = root[core_name]; - if(!val.isNull() && val.isArray()){ - delays.reserve(val.size()); - for(auto it:val){ - auto name = it["name"]; - auto size = it["size"]; - auto delay = it["delay"]; - if(!name.isString() || !size.isUInt() || !(delay.isUInt() || delay.isArray())) throw std::runtime_error("JSON parse error"); - if(delay.isUInt()){ - delays.push_back(instr_desc{size.asUInt(), delay.asUInt(), 0}); - } else { - delays.push_back(instr_desc{size.asUInt(), delay[0].asUInt(), delay[1].asUInt()}); - } - } - } else { - LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<get_instrumentation_if(); + if(!arch_instr) return false; + const string core_name = arch_instr->core_type_name(); + if (config_file_name.length() > 0) { + ifstream is(config_file_name); + if (is.is_open()) { + try { + IStreamWrapper isw(is); + Document d; + ParseResult ok = d.ParseStream(isw); + if(ok) { + Value& val = d[core_name]; + if(val.IsArray()){ + delays.reserve(val.Size()); + for(auto it:val.GetArray()){ + auto name = it["name"]; + auto size = it["size"]; + auto delay = it["delay"]; + if(delay.IsArray()) { + delays.push_back(instr_desc{size.Get(), delay[0].Get(), delay[1].Get()}); + } else if(delay.Is()) { + delays.push_back(instr_desc{size.Get(), delay.Get(), 0}); + } else + throw runtime_error("JSON parse error"); + } + } else { + LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<get_next_pc()-arch_instr->get_pc()) != (entry.size/8); + auto entry = delays[instr_info.instr_id]; + bool taken = (arch_instr->get_next_pc()-arch_instr->get_pc()) != (entry.size/8); if (taken && entry.taken > 1) arch_instr->set_curr_instr_cycles(entry.taken); else if (entry.not_taken > 1) diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index fedca0b..3b470b8 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -175,6 +175,15 @@ protected: auto sign_mask = 1ULL<<(W-1); return (from & mask) | ((from & sign_mask) ? ~mask : 0); } + + inline void process_spawn_blocks() { + for(auto it = std::begin(spawn_blocks); it!=std::end(spawn_blocks);) + if(*it){ + (*it)(); + ++it; + } else + spawn_blocks.erase(it); + } private: /**************************************************************************** @@ -397,7 +406,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)imm; } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 0); // trap check if(*trap_state!=0){ @@ -436,7 +445,7 @@ private: if(rd != 0) *(X+rd) = *PC + (int32_t)imm; } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 1); // trap check if(*trap_state!=0){ @@ -483,7 +492,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); // trap check if(*trap_state!=0){ @@ -532,7 +541,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3); // trap check if(*trap_state!=0){ @@ -579,7 +588,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); // trap check if(*trap_state!=0){ @@ -626,7 +635,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); // trap check if(*trap_state!=0){ @@ -673,7 +682,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); // trap check if(*trap_state!=0){ @@ -720,7 +729,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); // trap check if(*trap_state!=0){ @@ -767,7 +776,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); // trap check if(*trap_state!=0){ @@ -814,7 +823,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); // trap check if(*trap_state!=0){ @@ -857,7 +866,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10); // trap check if(*trap_state!=0){ @@ -901,7 +910,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11); // trap check if(*trap_state!=0){ @@ -945,7 +954,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12); // trap check if(*trap_state!=0){ @@ -988,7 +997,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13); // trap check if(*trap_state!=0){ @@ -1032,7 +1041,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14); // trap check if(*trap_state!=0){ @@ -1072,7 +1081,7 @@ private: writeSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2)); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); // trap check if(*trap_state!=0){ @@ -1115,7 +1124,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16); // trap check if(*trap_state!=0){ @@ -1158,7 +1167,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17); // trap check if(*trap_state!=0){ @@ -1198,7 +1207,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); // trap check if(*trap_state!=0){ @@ -1238,7 +1247,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); // trap check if(*trap_state!=0){ @@ -1278,7 +1287,7 @@ private: if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 20); // trap check if(*trap_state!=0){ @@ -1318,7 +1327,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); // trap check if(*trap_state!=0){ @@ -1358,7 +1367,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); // trap check if(*trap_state!=0){ @@ -1398,7 +1407,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); // trap check if(*trap_state!=0){ @@ -1443,7 +1452,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24); // trap check if(*trap_state!=0){ @@ -1488,7 +1497,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25); // trap check if(*trap_state!=0){ @@ -1533,7 +1542,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26); // trap check if(*trap_state!=0){ @@ -1573,7 +1582,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 27); // trap check if(*trap_state!=0){ @@ -1613,7 +1622,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 28); // trap check if(*trap_state!=0){ @@ -1653,7 +1662,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 29); // trap check if(*trap_state!=0){ @@ -1693,7 +1702,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 30); // trap check if(*trap_state!=0){ @@ -1733,7 +1742,7 @@ private: if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 31); // trap check if(*trap_state!=0){ @@ -1773,7 +1782,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 32); // trap check if(*trap_state!=0){ @@ -1813,7 +1822,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 33); // trap check if(*trap_state!=0){ @@ -1853,7 +1862,7 @@ private: if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 34); // trap check if(*trap_state!=0){ @@ -1893,7 +1902,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 35); // trap check if(*trap_state!=0){ @@ -1933,7 +1942,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 36); // trap check if(*trap_state!=0){ @@ -1974,7 +1983,7 @@ private: writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 37); // trap check if(*trap_state!=0){ @@ -2007,7 +2016,7 @@ private: raise(0, 11); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 38); // trap check if(*trap_state!=0){ @@ -2040,7 +2049,7 @@ private: raise(0, 3); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 39); // trap check if(*trap_state!=0){ @@ -2073,7 +2082,7 @@ private: leave(0); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 40); // trap check if(*trap_state!=0){ @@ -2106,7 +2115,7 @@ private: leave(1); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 41); // trap check if(*trap_state!=0){ @@ -2139,7 +2148,7 @@ private: leave(3); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 42); // trap check if(*trap_state!=0){ @@ -2172,7 +2181,7 @@ private: wait(1); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 43); // trap check if(*trap_state!=0){ @@ -2215,7 +2224,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); // trap check if(*trap_state!=0){ @@ -2265,7 +2274,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); // trap check if(*trap_state!=0){ @@ -2310,7 +2319,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); // trap check if(*trap_state!=0){ @@ -2355,7 +2364,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); // trap check if(*trap_state!=0){ @@ -2399,7 +2408,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); // trap check if(*trap_state!=0){ @@ -2443,7 +2452,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); // trap check if(*trap_state!=0){ @@ -2487,7 +2496,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); // trap check if(*trap_state!=0){ @@ -2526,7 +2535,7 @@ private: writeSpace2(traits::FENCE, traits::fencei, imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); // trap check if(*trap_state!=0){ @@ -2571,7 +2580,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); // trap check if(*trap_state!=0){ @@ -2616,7 +2625,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); // trap check if(*trap_state!=0){ @@ -2661,7 +2670,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); // trap check if(*trap_state!=0){ @@ -2706,7 +2715,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); // trap check if(*trap_state!=0){ @@ -2755,7 +2764,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); // trap check if(*trap_state!=0){ @@ -2800,7 +2809,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); // trap check if(*trap_state!=0){ @@ -2849,7 +2858,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); // trap check if(*trap_state!=0){ @@ -2894,7 +2903,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); // trap check if(*trap_state!=0){ @@ -2934,7 +2943,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); // trap check if(*trap_state!=0){ @@ -2977,7 +2986,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); // trap check if(*trap_state!=0){ @@ -3020,7 +3029,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); // trap check if(*trap_state!=0){ @@ -3059,7 +3068,7 @@ private: *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); // trap check if(*trap_state!=0){ @@ -3094,7 +3103,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); // trap check if(*trap_state!=0){ @@ -3135,7 +3144,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); // trap check if(*trap_state!=0){ @@ -3176,7 +3185,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); // trap check if(*trap_state!=0){ @@ -3218,7 +3227,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); // trap check if(*trap_state!=0){ @@ -3257,7 +3266,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); // trap check if(*trap_state!=0){ @@ -3291,7 +3300,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); // trap check if(*trap_state!=0){ @@ -3333,7 +3342,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); // trap check if(*trap_state!=0){ @@ -3379,7 +3388,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); // trap check if(*trap_state!=0){ @@ -3421,7 +3430,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); // trap check if(*trap_state!=0){ @@ -3463,7 +3472,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); // trap check if(*trap_state!=0){ @@ -3505,7 +3514,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); // trap check if(*trap_state!=0){ @@ -3547,7 +3556,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); // trap check if(*trap_state!=0){ @@ -3589,7 +3598,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); // trap check if(*trap_state!=0){ @@ -3626,7 +3635,7 @@ private: pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); // trap check if(*trap_state!=0){ @@ -3665,7 +3674,7 @@ private: if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); // trap check if(*trap_state!=0){ @@ -3704,7 +3713,7 @@ private: if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); // trap check if(*trap_state!=0){ @@ -3743,7 +3752,7 @@ private: if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); // trap check if(*trap_state!=0){ @@ -3786,7 +3795,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); // trap check if(*trap_state!=0){ @@ -3825,7 +3834,7 @@ private: if(rd != 0) *(X+rd) = *(X+rs2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); // trap check if(*trap_state!=0){ @@ -3864,7 +3873,7 @@ private: else raise(0, 2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); // trap check if(*trap_state!=0){ @@ -3897,7 +3906,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); // trap check if(*trap_state!=0){ @@ -3936,7 +3945,7 @@ private: if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); // trap check if(*trap_state!=0){ @@ -3978,7 +3987,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); // trap check if(*trap_state!=0){ @@ -4011,7 +4020,7 @@ private: raise(0, 3); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); // trap check if(*trap_state!=0){ @@ -4053,7 +4062,7 @@ private: } } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 88); // trap check if(*trap_state!=0){ @@ -4086,7 +4095,7 @@ private: raise(0, 2); } catch(...){} // post execution stuff - for(auto& spawn_block:spawn_blocks) spawn_block(); + process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 89); // trap check if(*trap_state!=0){ From 98b418ff438e5d1966dbc6b7642deeaf18caea0e Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 1 Feb 2022 19:28:11 +0100 Subject: [PATCH 16/41] fix JSON reading --- CMakeLists.txt | 8 +++++++- incl/iss/plugin/cycle_estimate.h | 1 + src/plugin/cycle_estimate.cpp | 13 +++++++------ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c94083..3a6d588 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,12 +35,14 @@ FILE(GLOB TGC_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp) set(LIB_SOURCES src/vm/fp_functions.cpp src/plugin/instruction_count.cpp - src/plugin/cycle_estimate.cpp src/plugin/cov.cpp ${TGC_SOURCES} ${TGC_VM_SOURCES} ) +if(TARGET RapidJSON) + list(APPEND LIB_SOURCES src/plugin/cycle_estimate.cpp) +endif() if(WITH_LLVM) FILE(GLOB TGC_LLVM_SOURCES @@ -82,6 +84,10 @@ elseif(TARGET elfio::elfio) else() message(FATAL_ERROR "No elfio library found, maybe a find_package() call is missing") endif() +if(TARGET RapidJSON) + target_link_libraries(${PROJECT_NAME} PUBLIC RapidJSON) +endif() + set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} diff --git a/incl/iss/plugin/cycle_estimate.h b/incl/iss/plugin/cycle_estimate.h index c2c9666..3f35dc7 100644 --- a/incl/iss/plugin/cycle_estimate.h +++ b/incl/iss/plugin/cycle_estimate.h @@ -39,6 +39,7 @@ #include "iss/vm_plugin.h" #include #include +#include namespace iss { diff --git a/src/plugin/cycle_estimate.cpp b/src/plugin/cycle_estimate.cpp index bf642f1..d2bcdad 100644 --- a/src/plugin/cycle_estimate.cpp +++ b/src/plugin/cycle_estimate.cpp @@ -41,6 +41,7 @@ #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include +#include #include using namespace rapidjson; @@ -67,13 +68,13 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& Document d; ParseResult ok = d.ParseStream(isw); if(ok) { - Value& val = d[core_name]; + Value& val = d[core_name.c_str()]; if(val.IsArray()){ delays.reserve(val.Size()); - for(auto it:val.GetArray()){ - auto name = it["name"]; - auto size = it["size"]; - auto delay = it["delay"]; + for (auto it = val.Begin(); it != val.End(); ++it) { + auto& name = (*it)["name"]; + auto& size = (*it)["size"]; + auto& delay = (*it)["delay"]; if(delay.IsArray()) { delays.push_back(instr_desc{size.Get(), delay[0].Get(), delay[1].Get()}); } else if(delay.Is()) { @@ -86,7 +87,7 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& return false; } } else { - LOG(ERR)<<"plugin cycle_estimate: could not parse in JSON file"< Date: Tue, 1 Feb 2022 21:14:50 +0100 Subject: [PATCH 17/41] fix cycle estimation plugin --- incl/iss/arch/riscv_hart_m_p.h | 2 +- incl/iss/arch/riscv_hart_msu_vp.h | 2 +- incl/iss/arch/riscv_hart_mu_p.h | 2 +- incl/iss/plugin/cycle_estimate.h | 6 ++++-- src/plugin/cycle_estimate.cpp | 14 +++++++++----- src/sysc/core_complex.cpp | 3 ++- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 36d31c9..b50b990 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -201,7 +201,7 @@ public: void disass_output(uint64_t pc, const std::string instr) override { CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [s:0x{:x};c:{}]", - pc, instr, (reg_t)state.mstatus, this->reg.icount); + pc, instr, (reg_t)state.mstatus, this->reg.icount + cycle_offset); }; iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; } diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index 5ac10f1..196cae5 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -307,7 +307,7 @@ public: void disass_output(uint64_t pc, const std::string instr) override { CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", - pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.ccount); + pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.ccount + cycle_offset); }; iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; } diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 99d1803..754ea1c 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -216,7 +216,7 @@ public: void disass_output(uint64_t pc, const std::string instr) override { CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", - pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.icount); + pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.icount + cycle_offset); }; iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; } diff --git a/incl/iss/plugin/cycle_estimate.h b/incl/iss/plugin/cycle_estimate.h index 3f35dc7..0c2cc15 100644 --- a/incl/iss/plugin/cycle_estimate.h +++ b/incl/iss/plugin/cycle_estimate.h @@ -49,11 +49,13 @@ class cycle_estimate: public iss::vm_plugin { BEGIN_BF_DECL(instr_desc, uint32_t) BF_FIELD(taken, 24, 8) BF_FIELD(not_taken, 16, 8) - BF_FIELD(size, 0, 16) - instr_desc(uint32_t size, uint32_t taken, uint32_t not_taken): instr_desc() { + BF_FIELD(is_branch, 8, 8) + BF_FIELD(size, 0, 8) + instr_desc(uint32_t size, uint32_t taken, uint32_t not_taken, bool branch): instr_desc() { this->size=size; this->taken=taken; this->not_taken=not_taken; + this->is_branch=branch; } END_BF_DECL(); diff --git a/src/plugin/cycle_estimate.cpp b/src/plugin/cycle_estimate.cpp index d2bcdad..88e275a 100644 --- a/src/plugin/cycle_estimate.cpp +++ b/src/plugin/cycle_estimate.cpp @@ -75,10 +75,14 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& auto& name = (*it)["name"]; auto& size = (*it)["size"]; auto& delay = (*it)["delay"]; + auto& branch = (*it)["branch"]; if(delay.IsArray()) { - delays.push_back(instr_desc{size.Get(), delay[0].Get(), delay[1].Get()}); + auto dt = delay[0].Get(); + auto dnt = delay[1].Get(); + delays.push_back(instr_desc{size.Get(), dt, dnt, branch.Get()}); } else if(delay.Is()) { - delays.push_back(instr_desc{size.Get(), delay.Get(), 0}); + auto d = delay.Get(); + delays.push_back(instr_desc{size.Get(), d, d, branch.Get()}); } else throw runtime_error("JSON parse error"); } @@ -103,11 +107,11 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& } -void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info const&) { +void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info const& exc_info) { assert(arch_instr && "No instrumentation interface available but callback executed"); auto entry = delays[instr_info.instr_id]; - bool taken = (arch_instr->get_next_pc()-arch_instr->get_pc()) != (entry.size/8); - if (taken && entry.taken > 1) + bool taken = exc_info.branch_taken; + if (exc_info.branch_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/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index c89f61f..8ec288d 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -136,7 +136,8 @@ public: if (!owner->disass_output(pc, instr)) { std::stringstream s; s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0') - << std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:" << this->reg.icount << "]"; + << std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:" + << this->reg.icount + this->cycle_offset << "]"; SCCDEBUG(owner->name())<<"disass: " << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40) << std::setfill(' ') << std::left << instr << s.str(); From 68b5697c8f1acb7c739bcb4454abce0c89379221 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 1 Feb 2022 21:48:56 +0100 Subject: [PATCH 18/41] Fix cycles JSON template --- gen_input/templates/CORENAME_cyles.txt.gtl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen_input/templates/CORENAME_cyles.txt.gtl b/gen_input/templates/CORENAME_cyles.txt.gtl index cef9f6f..1202094 100644 --- a/gen_input/templates/CORENAME_cyles.txt.gtl +++ b/gen_input/templates/CORENAME_cyles.txt.gtl @@ -3,8 +3,8 @@ { "name" : "${instr.name}", "size" : ${instr.length}, - "encoding": ${instr.encoding}, - "mask": ${instr.mask}, + "encoding": "${instr.encoding}", + "mask": "${instr.mask}", "branch": ${instr.modifiesPC}, "delay" : ${instr.isConditional?"[1,1]":"1"} }<%}%> From ac86f14a54699647590b57455b437c337995f1d1 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 2 Feb 2022 21:33:42 +0100 Subject: [PATCH 19/41] add tgc_c_xrb_nn to tgc-sim --- src/main.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index ee978e3..88c9812 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,11 @@ using tgc_c_plat_type = iss::arch::riscv_hart_m_p; #include "iss/arch/tgc_b.h" using tgc_b_plat_type = iss::arch::riscv_hart_m_p; #endif +#ifdef CORE_TGC_C_XRB_NN +#include "iss/arch/riscv_hart_m_p.h" +#include "iss/arch/tgc_c_xrb_nn.h" +using tgc_c_xrb_nn_plat_type = iss::arch::riscv_hart_m_p; +#endif #ifdef CORE_TGC_D #include "iss/arch/riscv_hart_mu_p.h" #include "iss/arch/tgc_d.h" @@ -152,6 +157,12 @@ int main(int argc, char *argv[]) { iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); } else #endif +#ifdef CORE_TGC_C_XRB_NN + if (isa_opt == "tgc_c_xrb_nn") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#endif #ifdef CORE_TGC_D if (isa_opt == "tgc_d") { std::tie(cpu, vm) = From b8fa5fbbda1690ff37d0357b55440bc548d80dbe Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 9 Feb 2022 21:01:17 +0100 Subject: [PATCH 20/41] adapt to extended instrumentation interface --- gen_input/templates/CORENAME.h.gtl | 1 - incl/iss/arch/riscv_hart_m_p.h | 4 ++++ incl/iss/arch/riscv_hart_msu_vp.h | 4 ++++ incl/iss/arch/riscv_hart_mu_p.h | 4 ++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/gen_input/templates/CORENAME.h.gtl b/gen_input/templates/CORENAME.h.gtl index fa69704..dbe4c82 100644 --- a/gen_input/templates/CORENAME.h.gtl +++ b/gen_input/templates/CORENAME.h.gtl @@ -169,7 +169,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { }}%> uint32_t trap_state = 0, pending_trap = 0; uint64_t icount = 0; - uint64_t cycle = 0; uint64_t instret = 0; uint32_t last_branch; } reg; diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index b50b990..91dd7b4 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -237,6 +237,10 @@ protected: uint64_t get_next_pc() override { return arch.get_next_pc(); }; + uint64_t get_instr_count() { return arch.reg.icount; } + + uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; } + void set_curr_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; }; riscv_hart_m_p &arch; diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index 196cae5..4ba669e 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -340,6 +340,10 @@ protected: virtual uint64_t get_next_pc() { return arch.get_next_pc(); }; + uint64_t get_instr_count() { return arch.reg.icount; } + + uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; } + virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; }; riscv_hart_msu_vp &arch; diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 754ea1c..ab0444c 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -252,6 +252,10 @@ protected: virtual uint64_t get_next_pc() { return arch.get_next_pc(); }; + uint64_t get_instr_count() { return arch.reg.icount; } + + uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; } + virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; }; riscv_hart_mu_p &arch; From 4c363f40736f286daef201407220763d962544ab Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Fri, 11 Feb 2022 11:28:00 +0100 Subject: [PATCH 21/41] adds additional functionality by fetching delay information --- CMakeLists.txt | 2 +- incl/iss/plugin/{cov.h => pctrace.h} | 18 +++++- src/plugin/cov.cpp | 32 --------- src/plugin/cycle_estimate.cpp | 4 +- src/plugin/pctrace.cpp | 97 ++++++++++++++++++++++++++++ src/sysc/core_complex.cpp | 6 +- 6 files changed, 119 insertions(+), 40 deletions(-) rename incl/iss/plugin/{cov.h => pctrace.h} (83%) delete mode 100644 src/plugin/cov.cpp create mode 100644 src/plugin/pctrace.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a6d588..6fa3d9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ FILE(GLOB TGC_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp) set(LIB_SOURCES src/vm/fp_functions.cpp src/plugin/instruction_count.cpp - src/plugin/cov.cpp + src/plugin/pctrace.cpp ${TGC_SOURCES} ${TGC_VM_SOURCES} diff --git a/incl/iss/plugin/cov.h b/incl/iss/plugin/pctrace.h similarity index 83% rename from incl/iss/plugin/cov.h rename to incl/iss/plugin/pctrace.h index 1f0c9bd..0cad8b0 100644 --- a/incl/iss/plugin/cov.h +++ b/incl/iss/plugin/pctrace.h @@ -52,6 +52,18 @@ class cov : public iss::vm_plugin { size_t not_taken_delay; size_t taken_delay; }; + BEGIN_BF_DECL(instr_desc, uint32_t) + BF_FIELD(taken, 24, 8) + BF_FIELD(not_taken, 16, 8) + BF_FIELD(is_branch, 8, 8) + BF_FIELD(size, 0, 8) + instr_desc(uint32_t size, uint32_t taken, uint32_t not_taken, bool branch): instr_desc() { + this->size=size; + this->taken=taken; + this->not_taken=not_taken; + this->is_branch=branch; + } + END_BF_DECL(); public: @@ -59,7 +71,7 @@ public: cov(const cov &&) = delete; - cov(); + cov(std::string const &); virtual ~cov(); @@ -75,8 +87,10 @@ public: private: iss::instrumentation_if *instr_if {nullptr}; - int counter {0}; std::ofstream output; + std::string filename; + std::vector delays; + }; } } diff --git a/src/plugin/cov.cpp b/src/plugin/cov.cpp deleted file mode 100644 index 46b1d32..0000000 --- a/src/plugin/cov.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include - - -iss::plugin::cov::cov() { - std::cout << "Entering Constructor"<get_instrumentation_if(); - return true; -} -void iss::plugin::cov::callback(instr_info_t iinfo, const exec_info&) { -// if((instr_if->get_next_pc() - instr_if->get_pc() != 4) ||( instr_if->get_next_pc() - instr_if->get_pc() != 2)){ -// std::cout << "jump from " << std::hex << instr_if->get_pc() << " to " << instr_if->get_next_pc()<< " after " << std::dec << counter <<" linear instructions" <get_pc() << std::endl; -} diff --git a/src/plugin/cycle_estimate.cpp b/src/plugin/cycle_estimate.cpp index 88e275a..f68d241 100644 --- a/src/plugin/cycle_estimate.cpp +++ b/src/plugin/cycle_estimate.cpp @@ -85,7 +85,7 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& delays.push_back(instr_desc{size.Get(), d, d, branch.Get()}); } else throw runtime_error("JSON parse error"); - } + } } else { LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "< 1) + if (exc_info.branch_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/pctrace.cpp b/src/plugin/pctrace.cpp new file mode 100644 index 0000000..1a92dd4 --- /dev/null +++ b/src/plugin/pctrace.cpp @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" +#include +#include +#include + +#include + + +using namespace rapidjson; +using namespace std; + +iss::plugin::cov::cov(std::string const &filename) + : instr_if(nullptr) + , filename(filename) +{ + output.open("output.trc"); +} + +iss::plugin::cov::~cov() { + output.close(); +} + +bool iss::plugin::cov::registration(const char *const version, vm_if& vm) { + instr_if = vm.get_arch()->get_instrumentation_if(); + if(!instr_if) return false; + const string core_name = instr_if->core_type_name(); + if (filename.length() > 0) { + ifstream is(filename); + if (is.is_open()) { + try { + IStreamWrapper isw(is); + Document d; + ParseResult ok = d.ParseStream(isw); + if(ok) { + Value& val = d[core_name.c_str()]; + if(val.IsArray()){ + delays.reserve(val.Size()); + for (auto it = val.Begin(); it != val.End(); ++it) { + auto& name = (*it)["name"]; + auto& size = (*it)["size"]; + auto& delay = (*it)["delay"]; + auto& branch = (*it)["branch"]; + if(delay.IsArray()) { + auto dt = delay[0].Get(); + auto dnt = delay[1].Get(); + delays.push_back(instr_desc{size.Get(), dt, dnt, branch.Get()}); + } else if(delay.Is()) { + auto d = delay.Get(); + delays.push_back(instr_desc{size.Get(), d, d, branch.Get()}); + } else + throw runtime_error("JSON parse error"); + + } + } else { + LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<get_next_pc() - instr_if->get_pc() != 4) ||( instr_if->get_next_pc() - instr_if->get_pc() != 2)){ +// std::cout << "jump from " << std::hex << instr_if->get_pc() << " to " << instr_if->get_next_pc()<< " after " << std::dec << counter <<" linear instructions" <get_pc() <<"," << delay << "\n"; +} diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 8ec288d..23ab3e5 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -69,7 +69,7 @@ using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p #include #include -#include +#include // clang-format on @@ -426,8 +426,8 @@ void core_complex::before_end_of_elaboration() { auto *plugin = new iss::plugin::cycle_estimate(filename); cpu->vm->register_plugin(*plugin); plugin_list.push_back(plugin); - } else if (plugin_name == "cov") { - auto *plugin = new iss::plugin::cov(); + } else if (plugin_name == "pctrace") { + auto *plugin = new iss::plugin::cov(filename); cpu->vm->register_plugin(*plugin); plugin_list.push_back(plugin); } else { From b37ef973de5ae7db9f988c1612404418c7fb5130 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 14 Feb 2022 20:36:12 +0100 Subject: [PATCH 22/41] clean up --- incl/iss/arch/tgc_c.h | 1 - 1 file changed, 1 deletion(-) diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index 975c205..c9528bb 100644 --- a/incl/iss/arch/tgc_c.h +++ b/incl/iss/arch/tgc_c.h @@ -258,7 +258,6 @@ struct tgc_c: public arch_if { uint32_t DPC = 0; uint32_t trap_state = 0, pending_trap = 0; uint64_t icount = 0; - uint64_t cycle = 0; uint64_t instret = 0; uint32_t last_branch; } reg; From bf0a5a80dea775492d01c8e251ca1dbc2cfa5109 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Wed, 16 Feb 2022 10:12:45 +0100 Subject: [PATCH 23/41] adds functionality to reduce the output --- incl/iss/plugin/pctrace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/incl/iss/plugin/pctrace.h b/incl/iss/plugin/pctrace.h index 0cad8b0..d227666 100644 --- a/incl/iss/plugin/pctrace.h +++ b/incl/iss/plugin/pctrace.h @@ -90,6 +90,7 @@ private: std::ofstream output; std::string filename; std::vector delays; + bool jumped, first; }; } From 2bba5645c33713703cb48038f1fa56d776586b5f Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Wed, 16 Feb 2022 10:12:45 +0100 Subject: [PATCH 24/41] adds functionality to reduce the output --- incl/iss/plugin/pctrace.h | 1 + src/plugin/pctrace.cpp | 52 +++++++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/incl/iss/plugin/pctrace.h b/incl/iss/plugin/pctrace.h index 0cad8b0..d227666 100644 --- a/incl/iss/plugin/pctrace.h +++ b/incl/iss/plugin/pctrace.h @@ -90,6 +90,7 @@ private: std::ofstream output; std::string filename; std::vector delays; + bool jumped, first; }; } diff --git a/src/plugin/pctrace.cpp b/src/plugin/pctrace.cpp index 1a92dd4..97ca4fc 100644 --- a/src/plugin/pctrace.cpp +++ b/src/plugin/pctrace.cpp @@ -20,6 +20,8 @@ iss::plugin::cov::cov(std::string const &filename) , filename(filename) { output.open("output.trc"); + jumped = false; + first = true; } iss::plugin::cov::~cov() { @@ -79,19 +81,53 @@ bool iss::plugin::cov::registration(const char *const version, vm_if& vm) { } + +inline string formatPC(uint64_t pc) { + stringstream stream; + stream << "0x" << std::hex << pc; + return stream.str(); +} + void iss::plugin::cov::callback(instr_info_t iinfo, const exec_info& einfo) { -// if((instr_if->get_next_pc() - instr_if->get_pc() != 4) ||( instr_if->get_next_pc() - instr_if->get_pc() != 2)){ -// std::cout << "jump from " << std::hex << instr_if->get_pc() << " to " << instr_if->get_next_pc()<< " after " << std::dec << counter <<" linear instructions" <get_pc() <<"," << delay << "\n"; + delay = entry.not_taken; + + if (first){ + output << formatPC(instr_if->get_pc()) << "," << delay; + first = false; + } + if(instr_if->get_next_pc()-instr_if->get_pc() != delays[iinfo.instr_id].size/8){ + //The goal is to keep the output in start-target pairs, so after a jump the target address needs to get written + //to the output. If the target happens to also be a start, we keep the pairing by adding a 0-delay entry. + if (jumped) + output <<"\n" <get_pc()) << "," << 0; + output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; + jumped = true; + } + else{ + if (jumped){ + output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; + jumped = false; + } + else if(delay!=1){ + output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; + output <<"\n" << formatPC(instr_if->get_pc()) << "," << 0; + } + + } + +//source code for the full output +// auto delay = 0; +// auto entry = delays[iinfo.instr_id]; +// bool taken = einfo.branch_taken; +// if (einfo.branch_taken) +// delay = entry.taken; +// else +// delay = entry.not_taken; +// output<get_pc() <<"," << delay << "\n"; } From 521f40a3d6c390c6c3f35f38ccae34777b4b40db Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 5 Mar 2022 20:59:17 +0100 Subject: [PATCH 25/41] refactored interpreter backend structure --- gen_input/templates/interp/CORENAME.cpp.gtl | 136 +- src/vm/interp/vm_tgc_c.cpp | 6092 +++++++------------ 2 files changed, 2208 insertions(+), 4020 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 119c084..084bafd 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -94,7 +94,7 @@ protected: inline const char *name(size_t index){return traits::reg_aliases.at(index);} - compile_func decode_inst(code_word_t instr) ; + typename arch::traits::opcode_e decode_inst_id(code_word_t instr); virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override; // some compile time constants @@ -114,7 +114,7 @@ protected: struct instruction_pattern { uint32_t value; uint32_t mask; - compile_func opc; + typename arch::traits::opcode_e id; }; std::array, 4> qlut; @@ -201,73 +201,13 @@ private: size_t length; uint32_t value; uint32_t mask; - compile_func op; + typename arch::traits::opcode_e op; }; const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %> - /* instruction ${instr.instruction.name} */ - {${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%> + {${instr.length}, ${instr.encoding}, ${instr.mask}, arch::traits::opcode_e::${instr.instruction.name}},<%}%> }}; - - /* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %> - /* instruction ${idx}: ${instr.name} */ - compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, ${idx}); - <%instr.fields.eachLine{%>${it} - <%}%>if(this->disass_enabled){ - /* generate console output when executing the command */ - <%instr.disass.eachLine{%>${it} - <%}%> - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // 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}]); - <%}}%>// calculate next pc value - *NEXT_PC = *PC + ${instr.length/8}; - // execute instruction - try { - <%instr.behavior.eachLine{%>${it} - <%}%>} catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx}); - // 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; - } - <%}%> - /**************************************************************************** - * end opcode definitions - ****************************************************************************/ - compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr) { - this->do_sync(PRE_SYNC, static_cast(arch::traits::opcode_e::MAX_OPCODE)); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); - uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2); - raise(0, 2); - // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast(arch::traits::opcode_e::MAX_OPCODE)); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // trap check - if(*trap_state!=0){ - super::core.enter_trap(*trap_state, pc.val, instr); - } - pc.val=*NEXT_PC; - return pc; - } //static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK; iss::status fetch_ins(virt_addr_t pc, uint8_t * data){ @@ -307,6 +247,7 @@ constexpr size_t bit_count(uint32_t u) { template vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) : vm_base(core, core_id, cluster_id) { + unsigned id=0; for (auto instr : instr_descr) { auto quadrant = instr.value & 0x3; qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op}); @@ -327,31 +268,74 @@ inline bool is_jump_to_self_enabled(finish_cond_e cond){ } template -typename vm_impl::compile_func vm_impl::decode_inst(code_word_t instr){ +typename arch::traits::opcode_e vm_impl::decode_inst_id(code_word_t instr){ for(auto& e: qlut[instr&0x3]){ - if(!((instr&e.mask) ^ e.value )) return e.opc; + if(!((instr&e.mask) ^ e.value )) return e.id; } - return &this_class::illegal_intruction; + return arch::traits::opcode_e::MAX_OPCODE; } template typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){ // we fetch at max 4 byte, alignment is 2 - code_word_t insn = 0; - auto *const data = (uint8_t *)&insn; + code_word_t instr = 0; + auto *const data = (uint8_t *)&instr; auto pc=start; + + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + auto* icount = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]); + auto* instret = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]); + while(!this->core.should_stop() && !(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){ - auto res = fetch_ins(pc, data); - if(res!=iss::Ok){ + if(fetch_ins(pc, data)!=iss::Ok){ 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' - auto f = decode_inst(insn); - auto old_pc = pc.val; - pc = (this->*f)(pc, insn); + (instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0' + auto inst_id = decode_inst_id(instr); + // pre execution stuff + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast(inst_id)); + switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %> + case arch::traits::opcode_e::${instr.name}: { + <%instr.fields.eachLine{%>${it} + <%}%>if(this->disass_enabled){ + /* generate console output when executing the command */ + <%instr.disass.eachLine{%>${it} + <%}%> + } + // 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}]); + <%}}%>// calculate next pc value + *NEXT_PC = *PC + ${instr.length/8}; + // execute instruction + try { + <%instr.behavior.eachLine{%>${it} + <%}%>} catch(...){} + } + break;<%}%> + default: { + *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2); + raise(0, 2); + } + } + // post execution stuff + process_spawn_blocks(); + 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); + } else { + (*icount)++; + (*instret)++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; this->core.reg.PC = this->core.reg.NEXT_PC; this->core.reg.trap_state = this->core.reg.pending_trap; } @@ -359,7 +343,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co return pc; } -} // namespace mnrv32 +} template <> std::unique_ptr create(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 3b470b8..4f5f98d 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -88,7 +88,7 @@ protected: inline const char *name(size_t index){return traits::reg_aliases.at(index);} - compile_func decode_inst(code_word_t instr) ; + typename arch::traits::opcode_e decode_inst_id(code_word_t instr); virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override; // some compile time constants @@ -108,7 +108,7 @@ protected: struct instruction_pattern { uint32_t value; uint32_t mask; - compile_func opc; + typename arch::traits::opcode_e id; }; std::array, 4> qlut; @@ -193,3941 +193,102 @@ private: size_t length; uint32_t value; uint32_t mask; - compile_func op; + typename arch::traits::opcode_e op; }; const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */ - /* instruction LUI */ - {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, - /* instruction AUIPC */ - {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, &this_class::__auipc}, - /* instruction JAL */ - {32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, &this_class::__jal}, - /* instruction JALR */ - {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, &this_class::__jalr}, - /* instruction BEQ */ - {32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, &this_class::__beq}, - /* instruction BNE */ - {32, 0b00000000000000000001000001100011, 0b00000000000000000111000001111111, &this_class::__bne}, - /* instruction BLT */ - {32, 0b00000000000000000100000001100011, 0b00000000000000000111000001111111, &this_class::__blt}, - /* instruction BGE */ - {32, 0b00000000000000000101000001100011, 0b00000000000000000111000001111111, &this_class::__bge}, - /* instruction BLTU */ - {32, 0b00000000000000000110000001100011, 0b00000000000000000111000001111111, &this_class::__bltu}, - /* instruction BGEU */ - {32, 0b00000000000000000111000001100011, 0b00000000000000000111000001111111, &this_class::__bgeu}, - /* instruction LB */ - {32, 0b00000000000000000000000000000011, 0b00000000000000000111000001111111, &this_class::__lb}, - /* instruction LH */ - {32, 0b00000000000000000001000000000011, 0b00000000000000000111000001111111, &this_class::__lh}, - /* instruction LW */ - {32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, &this_class::__lw}, - /* instruction LBU */ - {32, 0b00000000000000000100000000000011, 0b00000000000000000111000001111111, &this_class::__lbu}, - /* instruction LHU */ - {32, 0b00000000000000000101000000000011, 0b00000000000000000111000001111111, &this_class::__lhu}, - /* instruction SB */ - {32, 0b00000000000000000000000000100011, 0b00000000000000000111000001111111, &this_class::__sb}, - /* instruction SH */ - {32, 0b00000000000000000001000000100011, 0b00000000000000000111000001111111, &this_class::__sh}, - /* instruction SW */ - {32, 0b00000000000000000010000000100011, 0b00000000000000000111000001111111, &this_class::__sw}, - /* instruction ADDI */ - {32, 0b00000000000000000000000000010011, 0b00000000000000000111000001111111, &this_class::__addi}, - /* instruction SLTI */ - {32, 0b00000000000000000010000000010011, 0b00000000000000000111000001111111, &this_class::__slti}, - /* instruction SLTIU */ - {32, 0b00000000000000000011000000010011, 0b00000000000000000111000001111111, &this_class::__sltiu}, - /* instruction XORI */ - {32, 0b00000000000000000100000000010011, 0b00000000000000000111000001111111, &this_class::__xori}, - /* instruction ORI */ - {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, &this_class::__ori}, - /* instruction ANDI */ - {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi}, - /* instruction SLLI */ - {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, &this_class::__slli}, - /* instruction SRLI */ - {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srli}, - /* instruction SRAI */ - {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srai}, - /* instruction ADD */ - {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add}, - /* instruction SUB */ - {32, 0b01000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__sub}, - /* instruction SLL */ - {32, 0b00000000000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__sll}, - /* instruction SLT */ - {32, 0b00000000000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__slt}, - /* instruction SLTU */ - {32, 0b00000000000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__sltu}, - /* instruction XOR */ - {32, 0b00000000000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__xor}, - /* instruction SRL */ - {32, 0b00000000000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__srl}, - /* instruction SRA */ - {32, 0b01000000000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__sra}, - /* instruction OR */ - {32, 0b00000000000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__or}, - /* instruction AND */ - {32, 0b00000000000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__and}, - /* instruction FENCE */ - {32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, &this_class::__fence}, - /* instruction ECALL */ - {32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, &this_class::__ecall}, - /* instruction EBREAK */ - {32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, &this_class::__ebreak}, - /* instruction URET */ - {32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__uret}, - /* instruction SRET */ - {32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__sret}, - /* instruction MRET */ - {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 */ - {32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, &this_class::__csrrs}, - /* instruction CSRRC */ - {32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, &this_class::__csrrc}, - /* instruction CSRRWI */ - {32, 0b00000000000000000101000001110011, 0b00000000000000000111000001111111, &this_class::__csrrwi}, - /* instruction CSRRSI */ - {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 */ - {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, - /* instruction MULHSU */ - {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, - /* instruction MULHU */ - {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, - /* instruction DIV */ - {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, - /* instruction DIVU */ - {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, - /* instruction REM */ - {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, - /* instruction REMU */ - {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, - /* instruction CADDI4SPN */ - {16, 0b0000000000000000, 0b1110000000000011, &this_class::__caddi4spn}, - /* instruction CLW */ - {16, 0b0100000000000000, 0b1110000000000011, &this_class::__clw}, - /* instruction CSW */ - {16, 0b1100000000000000, 0b1110000000000011, &this_class::__csw}, - /* instruction CADDI */ - {16, 0b0000000000000001, 0b1110000000000011, &this_class::__caddi}, - /* instruction CNOP */ - {16, 0b0000000000000001, 0b1110111110000011, &this_class::__cnop}, - /* instruction CJAL */ - {16, 0b0010000000000001, 0b1110000000000011, &this_class::__cjal}, - /* instruction CLI */ - {16, 0b0100000000000001, 0b1110000000000011, &this_class::__cli}, - /* instruction CLUI */ - {16, 0b0110000000000001, 0b1110000000000011, &this_class::__clui}, - /* instruction CADDI16SP */ - {16, 0b0110000100000001, 0b1110111110000011, &this_class::__caddi16sp}, - /* instruction __reserved_clui */ - {16, 0b0110000000000001, 0b1111000001111111, &this_class::____reserved_clui}, - /* instruction CSRLI */ - {16, 0b1000000000000001, 0b1111110000000011, &this_class::__csrli}, - /* instruction CSRAI */ - {16, 0b1000010000000001, 0b1111110000000011, &this_class::__csrai}, - /* instruction CANDI */ - {16, 0b1000100000000001, 0b1110110000000011, &this_class::__candi}, - /* instruction CSUB */ - {16, 0b1000110000000001, 0b1111110001100011, &this_class::__csub}, - /* instruction CXOR */ - {16, 0b1000110000100001, 0b1111110001100011, &this_class::__cxor}, - /* instruction COR */ - {16, 0b1000110001000001, 0b1111110001100011, &this_class::__cor}, - /* instruction CAND */ - {16, 0b1000110001100001, 0b1111110001100011, &this_class::__cand}, - /* instruction CJ */ - {16, 0b1010000000000001, 0b1110000000000011, &this_class::__cj}, - /* instruction CBEQZ */ - {16, 0b1100000000000001, 0b1110000000000011, &this_class::__cbeqz}, - /* instruction CBNEZ */ - {16, 0b1110000000000001, 0b1110000000000011, &this_class::__cbnez}, - /* instruction CSLLI */ - {16, 0b0000000000000010, 0b1111000000000011, &this_class::__cslli}, - /* instruction CLWSP */ - {16, 0b0100000000000010, 0b1110000000000011, &this_class::__clwsp}, - /* instruction CMV */ - {16, 0b1000000000000010, 0b1111000000000011, &this_class::__cmv}, - /* instruction CJR */ - {16, 0b1000000000000010, 0b1111000001111111, &this_class::__cjr}, - /* instruction __reserved_cmv */ - {16, 0b1000000000000010, 0b1111111111111111, &this_class::____reserved_cmv}, - /* instruction CADD */ - {16, 0b1001000000000010, 0b1111000000000011, &this_class::__cadd}, - /* instruction CJALR */ - {16, 0b1001000000000010, 0b1111000001111111, &this_class::__cjalr}, - /* instruction CEBREAK */ - {16, 0b1001000000000010, 0b1111111111111111, &this_class::__cebreak}, - /* instruction CSWSP */ - {16, 0b1100000000000010, 0b1110000000000011, &this_class::__cswsp}, - /* instruction DII */ - {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, + {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, arch::traits::opcode_e::LUI}, + {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, arch::traits::opcode_e::AUIPC}, + {32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, arch::traits::opcode_e::JAL}, + {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, arch::traits::opcode_e::JALR}, + {32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::BEQ}, + {32, 0b00000000000000000001000001100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::BNE}, + {32, 0b00000000000000000100000001100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::BLT}, + {32, 0b00000000000000000101000001100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::BGE}, + {32, 0b00000000000000000110000001100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::BLTU}, + {32, 0b00000000000000000111000001100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::BGEU}, + {32, 0b00000000000000000000000000000011, 0b00000000000000000111000001111111, arch::traits::opcode_e::LB}, + {32, 0b00000000000000000001000000000011, 0b00000000000000000111000001111111, arch::traits::opcode_e::LH}, + {32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, arch::traits::opcode_e::LW}, + {32, 0b00000000000000000100000000000011, 0b00000000000000000111000001111111, arch::traits::opcode_e::LBU}, + {32, 0b00000000000000000101000000000011, 0b00000000000000000111000001111111, arch::traits::opcode_e::LHU}, + {32, 0b00000000000000000000000000100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::SB}, + {32, 0b00000000000000000001000000100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::SH}, + {32, 0b00000000000000000010000000100011, 0b00000000000000000111000001111111, arch::traits::opcode_e::SW}, + {32, 0b00000000000000000000000000010011, 0b00000000000000000111000001111111, arch::traits::opcode_e::ADDI}, + {32, 0b00000000000000000010000000010011, 0b00000000000000000111000001111111, arch::traits::opcode_e::SLTI}, + {32, 0b00000000000000000011000000010011, 0b00000000000000000111000001111111, arch::traits::opcode_e::SLTIU}, + {32, 0b00000000000000000100000000010011, 0b00000000000000000111000001111111, arch::traits::opcode_e::XORI}, + {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, arch::traits::opcode_e::ORI}, + {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, arch::traits::opcode_e::ANDI}, + {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SLLI}, + {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SRLI}, + {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SRAI}, + {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::ADD}, + {32, 0b01000000000000000000000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SUB}, + {32, 0b00000000000000000001000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SLL}, + {32, 0b00000000000000000010000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SLT}, + {32, 0b00000000000000000011000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SLTU}, + {32, 0b00000000000000000100000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::XOR}, + {32, 0b00000000000000000101000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SRL}, + {32, 0b01000000000000000101000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::SRA}, + {32, 0b00000000000000000110000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::OR}, + {32, 0b00000000000000000111000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::AND}, + {32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, arch::traits::opcode_e::FENCE}, + {32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, arch::traits::opcode_e::ECALL}, + {32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, arch::traits::opcode_e::EBREAK}, + {32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits::opcode_e::URET}, + {32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits::opcode_e::SRET}, + {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits::opcode_e::MRET}, + {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, arch::traits::opcode_e::WFI}, + {32, 0b01111011001000000000000001110011, 0b11111111111111111111111111111111, arch::traits::opcode_e::DRET}, + {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, arch::traits::opcode_e::CSRRW}, + {32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, arch::traits::opcode_e::CSRRS}, + {32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, arch::traits::opcode_e::CSRRC}, + {32, 0b00000000000000000101000001110011, 0b00000000000000000111000001111111, arch::traits::opcode_e::CSRRWI}, + {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, arch::traits::opcode_e::CSRRSI}, + {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, arch::traits::opcode_e::CSRRCI}, + {32, 0b00000000000000000001000000001111, 0b00000000000000000111000001111111, arch::traits::opcode_e::FENCE_I}, + {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::MUL}, + {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::MULH}, + {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::MULHSU}, + {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::MULHU}, + {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::DIV}, + {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::DIVU}, + {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::REM}, + {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, arch::traits::opcode_e::REMU}, + {16, 0b0000000000000000, 0b1110000000000011, arch::traits::opcode_e::CADDI4SPN}, + {16, 0b0100000000000000, 0b1110000000000011, arch::traits::opcode_e::CLW}, + {16, 0b1100000000000000, 0b1110000000000011, arch::traits::opcode_e::CSW}, + {16, 0b0000000000000001, 0b1110000000000011, arch::traits::opcode_e::CADDI}, + {16, 0b0000000000000001, 0b1110111110000011, arch::traits::opcode_e::CNOP}, + {16, 0b0010000000000001, 0b1110000000000011, arch::traits::opcode_e::CJAL}, + {16, 0b0100000000000001, 0b1110000000000011, arch::traits::opcode_e::CLI}, + {16, 0b0110000000000001, 0b1110000000000011, arch::traits::opcode_e::CLUI}, + {16, 0b0110000100000001, 0b1110111110000011, arch::traits::opcode_e::CADDI16SP}, + {16, 0b0110000000000001, 0b1111000001111111, arch::traits::opcode_e::__reserved_clui}, + {16, 0b1000000000000001, 0b1111110000000011, arch::traits::opcode_e::CSRLI}, + {16, 0b1000010000000001, 0b1111110000000011, arch::traits::opcode_e::CSRAI}, + {16, 0b1000100000000001, 0b1110110000000011, arch::traits::opcode_e::CANDI}, + {16, 0b1000110000000001, 0b1111110001100011, arch::traits::opcode_e::CSUB}, + {16, 0b1000110000100001, 0b1111110001100011, arch::traits::opcode_e::CXOR}, + {16, 0b1000110001000001, 0b1111110001100011, arch::traits::opcode_e::COR}, + {16, 0b1000110001100001, 0b1111110001100011, arch::traits::opcode_e::CAND}, + {16, 0b1010000000000001, 0b1110000000000011, arch::traits::opcode_e::CJ}, + {16, 0b1100000000000001, 0b1110000000000011, arch::traits::opcode_e::CBEQZ}, + {16, 0b1110000000000001, 0b1110000000000011, arch::traits::opcode_e::CBNEZ}, + {16, 0b0000000000000010, 0b1111000000000011, arch::traits::opcode_e::CSLLI}, + {16, 0b0100000000000010, 0b1110000000000011, arch::traits::opcode_e::CLWSP}, + {16, 0b1000000000000010, 0b1111000000000011, arch::traits::opcode_e::CMV}, + {16, 0b1000000000000010, 0b1111000001111111, arch::traits::opcode_e::CJR}, + {16, 0b1000000000000010, 0b1111111111111111, arch::traits::opcode_e::__reserved_cmv}, + {16, 0b1001000000000010, 0b1111000000000011, arch::traits::opcode_e::CADD}, + {16, 0b1001000000000010, 0b1111000001111111, arch::traits::opcode_e::CJALR}, + {16, 0b1001000000000010, 0b1111111111111111, arch::traits::opcode_e::CEBREAK}, + {16, 0b1100000000000010, 0b1110000000000011, arch::traits::opcode_e::CSWSP}, + {16, 0b0000000000000000, 0b1111111111111111, arch::traits::opcode_e::DII}, }}; - - /* instruction definitions */ - /* instruction 0: LUI */ - compile_ret_t __lui(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 0); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint32_t imm = ((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = (int32_t)imm; - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 0); - // 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 1: AUIPC */ - compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 1); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint32_t imm = ((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *PC + (int32_t)imm; - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 1); - // 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 2: JAL */ - compile_ret_t __jal(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 2); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint32_t imm = ((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - 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 - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); - // 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 3: JALR */ - compile_ret_t __jalr(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 3); - 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} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - int32_t new_pc = (*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 1; - if(new_pc % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - if(rd != 0) *(X+rd) = *PC + 4; - pc_assign(*NEXT_PC) = new_pc & ~ 0x1; - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3); - // 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 4: BEQ */ - compile_ret_t __beq(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 4); - uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - 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 - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); - // 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 5: BNE */ - compile_ret_t __bne(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 5); - uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - 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 - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); - // 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 6: BLT */ - compile_ret_t __blt(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 6); - uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - 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 - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); - // 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 7: BGE */ - compile_ret_t __bge(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 7); - uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - 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 - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); - // 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 8: BLTU */ - compile_ret_t __bltu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 8); - uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - 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 - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); - // 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 9: BGEU */ - compile_ret_t __bgeu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 9); - uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - 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 - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); - // 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 10: LB */ - compile_ret_t __lb(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 10); - 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); - if(rd != 0) *(X+rd) = res; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10); - // 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 11: LH */ - compile_ret_t __lh(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 11); - 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); - int16_t res = (int16_t)readSpace2(traits::MEM, load_address); - if(rd != 0) *(X+rd) = res; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11); - // 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 12: LW */ - compile_ret_t __lw(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 12); - 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); - int32_t res = (int32_t)readSpace4(traits::MEM, load_address); - if(rd != 0) *(X+rd) = (uint32_t)res; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12); - // 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 13: LBU */ - compile_ret_t __lbu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 13); - 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); - if(rd != 0) *(X+rd) = res; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13); - // 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 14: LHU */ - compile_ret_t __lhu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 14); - 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); - uint16_t res = (uint16_t)readSpace2(traits::MEM, load_address); - if(rd != 0) *(X+rd) = res; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14); - // 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 15: SB */ - compile_ret_t __sb(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 15); - uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - writeSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2)); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); - // 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 16: SH */ - compile_ret_t __sh(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 16); - uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); - writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16); - // 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 17: SW */ - compile_ret_t __sw(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 17); - uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); - writeSpace4(traits::MEM, store_address, *(X+rs2)); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17); - // 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 18: ADDI */ - compile_ret_t __addi(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 18); - 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); - // 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 19: SLTI */ - compile_ret_t __slti(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 19); - 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); - // 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 20: SLTIU */ - compile_ret_t __sltiu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 20); - 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 20); - // 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 21: XORI */ - compile_ret_t __xori(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 21); - 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); - // 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 22: ORI */ - compile_ret_t __ori(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 22); - 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); - // 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 23: ANDI */ - compile_ret_t __andi(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 23); - 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); - // 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 24: SLLI */ - compile_ret_t __slli(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 24); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(shamt > 31) { - raise(0, 0); - } - else { - if(rd != 0) *(X+rd) = *(X+rs1) << shamt; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24); - // 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 25: SRLI */ - compile_ret_t __srli(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 25); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(shamt > 31) { - raise(0, 0); - } - else { - if(rd != 0) *(X+rd) = *(X+rs1) >> shamt; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25); - // 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 26: SRAI */ - compile_ret_t __srai(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 26); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(shamt > 31) { - raise(0, 0); - } - else { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> shamt; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26); - // 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 27: ADD */ - compile_ret_t __add(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 27); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 27); - // 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 28: SUB */ - compile_ret_t __sub(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 28); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 28); - // 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 29: SLL */ - compile_ret_t __sll(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 29); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 29); - // 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 30: SLT */ - compile_ret_t __slt(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 30); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 30); - // 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 31: SLTU */ - compile_ret_t __sltu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 31); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 31); - // 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 32: XOR */ - compile_ret_t __xor(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 32); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 32); - // 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 33: SRL */ - compile_ret_t __srl(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 33); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 33); - // 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 34: SRA */ - compile_ret_t __sra(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 34); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 34); - // 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 35: OR */ - compile_ret_t __or(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 35); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 35); - // 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 36: AND */ - compile_ret_t __and(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 36); - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 36); - // 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 37: FENCE */ - compile_ret_t __fence(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 37); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t succ = ((bit_sub<20,4>(instr))); - uint8_t pred = ((bit_sub<24,4>(instr))); - uint8_t fm = ((bit_sub<28,4>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {pred}, {succ} ({fm} , {rs1}, {rd})", fmt::arg("mnemonic", "fence"), - fmt::arg("pred", pred), fmt::arg("succ", succ), fmt::arg("fm", fm), fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 37); - // 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 38: ECALL */ - compile_ret_t __ecall(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 38); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "ecall"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - raise(0, 11); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 38); - // 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 39: EBREAK */ - compile_ret_t __ebreak(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 39); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "ebreak"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - raise(0, 3); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 39); - // 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 40: URET */ - compile_ret_t __uret(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 40); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "uret"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - leave(0); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 40); - // 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 41: SRET */ - compile_ret_t __sret(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 41); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "sret"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - leave(1); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 41); - // 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 42: MRET */ - compile_ret_t __mret(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 42); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "mret"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - leave(3); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 42); - // 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 43: WFI */ - compile_ret_t __wfi(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, 43); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "wfi"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - wait(1); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 43); - // 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 44: DRET */ - compile_ret_t __dret(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // 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 - process_spawn_blocks(); - 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 - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t xrs1 = *(X+rs1); - if(rd != 0) { - uint32_t xrd = readSpace4(traits::CSR, csr); - writeSpace4(traits::CSR, csr, xrs1); - *(X+rd) = xrd; - } - else { - writeSpace4(traits::CSR, csr, xrs1); - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 46: CSRRS */ - compile_ret_t __csrrs(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t xrd = readSpace4(traits::CSR, csr); - uint32_t xrs1 = *(X+rs1); - if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); - if(rd != 0) *(X+rd) = xrd; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 47: CSRRC */ - compile_ret_t __csrrc(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t xrd = readSpace4(traits::CSR, csr); - uint32_t xrs1 = *(X+rs1); - if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); - if(rd != 0) *(X+rd) = xrd; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 48: CSRRWI */ - compile_ret_t __csrrwi(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t xrd = readSpace4(traits::CSR, csr); - writeSpace4(traits::CSR, csr, (uint32_t)zimm); - if(rd != 0) *(X+rd) = xrd; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 49: CSRRSI */ - compile_ret_t __csrrsi(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t xrd = readSpace4(traits::CSR, csr); - if(zimm != 0) writeSpace4(traits::CSR, csr, xrd | (uint32_t)zimm); - if(rd != 0) *(X+rd) = xrd; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 50: CSRRCI */ - compile_ret_t __csrrci(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - uint32_t xrd = readSpace4(traits::CSR, csr); - if(zimm != 0) writeSpace4(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); - if(rd != 0) *(X+rd) = xrd; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: FENCE_I */ - compile_ret_t __fence_i(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - 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); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - writeSpace2(traits::FENCE, traits::fencei, imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 52: MUL */ - compile_ret_t __mul(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - if(rd != 0) { - int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2); - *(X+rd) = (uint32_t)res; - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 53: MULH */ - compile_ret_t __mulh(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - if(rd != 0) { - int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2); - *(X+rd) = (uint32_t)(res >> traits::XLEN); - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 54: MULHSU */ - compile_ret_t __mulhsu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - if(rd != 0) { - int64_t res = (int64_t)(int32_t)*(X+rs1) * (uint64_t)*(X+rs2); - *(X+rd) = (uint32_t)(res >> traits::XLEN); - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 55: MULHU */ - compile_ret_t __mulhu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - if(rd != 0) { - uint64_t res = (uint64_t)*(X+rs1) * (uint64_t)*(X+rs2); - *(X+rd) = (uint32_t)(res >> traits::XLEN); - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 56: DIV */ - compile_ret_t __div(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - if(rd != 0) { - if(*(X+rs2) != 0) { - uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = MMIN; - else *(X+rd) = (int32_t)*(X+rs1) / (int32_t)*(X+rs2); - } - else *(X+rd) = - 1; - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 57: DIVU */ - compile_ret_t __divu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - if(rd != 0) { - if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) / *(X+rs2); - else *(X+rd) = - 1; - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 58: REM */ - compile_ret_t __rem(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - if(rd != 0) { - if(*(X+rs2) != 0) { - uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = 0; - else *(X+rd) = (int32_t)*(X+rs1) % (int32_t)*(X+rs2); - } - else *(X+rd) = *(X+rs1); - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 59: REMU */ - compile_ret_t __remu(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - { - if(rd != 0) { - if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) % *(X+rs2); - else *(X+rd) = *(X+rs1); - } - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 60: CADDI4SPN */ - compile_ret_t __caddi4spn(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "caddi4spn"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(imm) *(X+(rd + 8)) = *(X+2) + imm; - else raise(0, 2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 61: CLW */ - compile_ret_t __clw(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "clw"), - fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t load_address = *(X+(rs1 + 8)) + uimm; - *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 62: CSW */ - compile_ret_t __csw(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "csw"), - fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t load_address = *(X+(rs1 + 8)) + uimm; - writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8))); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 63: CADDI */ - compile_ret_t __caddi(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "caddi"), - fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 64: CNOP */ - compile_ret_t __cnop(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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 */ - this->core.disass_output(pc.val, "cnop"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 65: CJAL */ - compile_ret_t __cjal(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cjal"), - fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - *(X+1) = *PC + 2; - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 66: CLI */ - compile_ret_t __cli(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "cli"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - if(rd != 0) *(X+rd) = (uint32_t)(int32_t)sext<6>(imm); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: CLUI */ - compile_ret_t __clui(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "clui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - if(imm == 0) raise(0, 2); - if(rd != 0) *(X+rd) = (int32_t)sext<18>(imm); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: CADDI16SP */ - compile_ret_t __caddi16sp(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {nzimm:#05x}", fmt::arg("mnemonic", "caddi16sp"), - fmt::arg("nzimm", nzimm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(nzimm) *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm); - else raise(0, 2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: __reserved_clui */ - compile_ret_t ____reserved_clui(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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 - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrli"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = *(X+rs1_idx) >> shamt; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 71: CSRAI */ - compile_ret_t __csrai(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrai"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(shamt) { - uint32_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt; - } - else if(traits::XLEN == 128) { - uint32_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 72: CANDI */ - compile_ret_t __candi(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "candi"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 73: CSUB */ - compile_ret_t __csub(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "csub"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8)); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 74: CXOR */ - compile_ret_t __cxor(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cxor"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8)); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 75: COR */ - compile_ret_t __cor(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cor"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8)); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 76: CAND */ - compile_ret_t __cand(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cand"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8)); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 77: CJ */ - compile_ret_t __cj(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cj"), - fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 78: CBEQZ */ - compile_ret_t __cbeqz(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbeqz"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 79: CBNEZ */ - compile_ret_t __cbnez(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbnez"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 80: CSLLI */ - compile_ret_t __cslli(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {nzuimm}", fmt::arg("mnemonic", "cslli"), - fmt::arg("rs1", name(rs1)), fmt::arg("nzuimm", nzuimm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 81: CLWSP */ - compile_ret_t __clwsp(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "clwsp"), - fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(rd) { - uint32_t offs = *(X+2) + uimm; - *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); - } - else raise(0, 2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: CMV */ - compile_ret_t __cmv(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cmv"), - fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rs2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: CJR */ - compile_ret_t __cjr(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjr"), - fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(rs1) pc_assign(*NEXT_PC) = *(X+rs1) & ~ 0x1; - else raise(0, 2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: __reserved_cmv */ - compile_ret_t ____reserved_cmv(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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 - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cadd"), - fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: CJALR */ - compile_ret_t __cjalr(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjalr"), - fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - int32_t new_pc = *(X+rs1); - *(X+1) = *PC + 2; - pc_assign(*NEXT_PC) = new_pc & ~ 0x1; - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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: CEBREAK */ - compile_ret_t __cebreak(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 3); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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 - 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "cswsp"), - fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); - this->core.disass_output(pc.val, mnemonic); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers - auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - { - uint32_t offs = *(X+2) + uimm; - writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); - } - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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 89: DII */ - compile_ret_t __dii(virt_addr_t& pc, code_word_t instr){ - // pre execution stuff - 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"); - - } - 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]); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - } catch(...){} - // post execution stuff - process_spawn_blocks(); - 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); - } 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; - } - - /**************************************************************************** - * end opcode definitions - ****************************************************************************/ - compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr) { - this->do_sync(PRE_SYNC, static_cast(arch::traits::opcode_e::MAX_OPCODE)); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); - uint32_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2); - raise(0, 2); - // post execution stuff - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast(arch::traits::opcode_e::MAX_OPCODE)); - auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); - // trap check - if(*trap_state!=0){ - super::core.enter_trap(*trap_state, pc.val, instr); - } - pc.val=*NEXT_PC; - return pc; - } //static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK; iss::status fetch_ins(virt_addr_t pc, uint8_t * data){ @@ -4167,6 +328,7 @@ constexpr size_t bit_count(uint32_t u) { template vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) : vm_base(core, core_id, cluster_id) { + unsigned id=0; for (auto instr : instr_descr) { auto quadrant = instr.value & 0x3; qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op}); @@ -4187,31 +349,2073 @@ inline bool is_jump_to_self_enabled(finish_cond_e cond){ } template -typename vm_impl::compile_func vm_impl::decode_inst(code_word_t instr){ +typename arch::traits::opcode_e vm_impl::decode_inst_id(code_word_t instr){ for(auto& e: qlut[instr&0x3]){ - if(!((instr&e.mask) ^ e.value )) return e.opc; + if(!((instr&e.mask) ^ e.value )) return e.id; } - return &this_class::illegal_intruction; + return arch::traits::opcode_e::MAX_OPCODE; } template typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){ // we fetch at max 4 byte, alignment is 2 - code_word_t insn = 0; - auto *const data = (uint8_t *)&insn; + code_word_t instr = 0; + auto *const data = (uint8_t *)&instr; auto pc=start; + + 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]); + auto* trap_state = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::TRAP_STATE]); + auto* icount = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::ICOUNT]); + auto* instret = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::INSTRET]); + while(!this->core.should_stop() && !(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){ - auto res = fetch_ins(pc, data); - if(res!=iss::Ok){ + if(fetch_ins(pc, data)!=iss::Ok){ 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' - auto f = decode_inst(insn); - auto old_pc = pc.val; - pc = (this->*f)(pc, insn); + (instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0' + auto inst_id = decode_inst_id(instr); + // pre execution stuff + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast(inst_id)); + switch(inst_id){ + case arch::traits::opcode_e::LUI: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint32_t imm = ((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = (int32_t)imm; + } catch(...){} + } + break; + case arch::traits::opcode_e::AUIPC: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint32_t imm = ((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *PC + (int32_t)imm; + } catch(...){} + } + break; + case arch::traits::opcode_e::JAL: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint32_t imm = ((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + 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(...){} + } + break; + case arch::traits::opcode_e::JALR: { + 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} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + int32_t new_pc = (*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 1; + if(new_pc % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + if(rd != 0) *(X+rd) = *PC + 4; + pc_assign(*NEXT_PC) = new_pc & ~ 0x1; + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::BEQ: { + uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + 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(...){} + } + break; + case arch::traits::opcode_e::BNE: { + uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + 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(...){} + } + break; + case arch::traits::opcode_e::BLT: { + uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + 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(...){} + } + break; + case arch::traits::opcode_e::BGE: { + uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + 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(...){} + } + break; + case arch::traits::opcode_e::BLTU: { + uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + 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(...){} + } + break; + case arch::traits::opcode_e::BGEU: { + uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + 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(...){} + } + break; + case arch::traits::opcode_e::LB: { + 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); + if(rd != 0) *(X+rd) = res; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::LH: { + 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); + int16_t res = (int16_t)readSpace2(traits::MEM, load_address); + if(rd != 0) *(X+rd) = res; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::LW: { + 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); + int32_t res = (int32_t)readSpace4(traits::MEM, load_address); + if(rd != 0) *(X+rd) = (uint32_t)res; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::LBU: { + 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); + if(rd != 0) *(X+rd) = res; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::LHU: { + 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} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); + uint16_t res = (uint16_t)readSpace2(traits::MEM, load_address); + if(rd != 0) *(X+rd) = res; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::SB: { + uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + writeSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2)); + } catch(...){} + } + break; + case arch::traits::opcode_e::SH: { + uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); + writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::SW: { + uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); + writeSpace4(traits::MEM, store_address, *(X+rs2)); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::ADDI: { + 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); + } catch(...){} + } + break; + case arch::traits::opcode_e::SLTI: { + 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; + } catch(...){} + } + break; + case arch::traits::opcode_e::SLTIU: { + 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; + } catch(...){} + } + break; + case arch::traits::opcode_e::XORI: { + 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); + } catch(...){} + } + break; + case arch::traits::opcode_e::ORI: { + 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); + } catch(...){} + } + break; + case arch::traits::opcode_e::ANDI: { + 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} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); + } catch(...){} + } + break; + case arch::traits::opcode_e::SLLI: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(shamt > 31) { + raise(0, 0); + } + else { + if(rd != 0) *(X+rd) = *(X+rs1) << shamt; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::SRLI: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(shamt > 31) { + raise(0, 0); + } + else { + if(rd != 0) *(X+rd) = *(X+rs1) >> shamt; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::SRAI: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(shamt > 31) { + raise(0, 0); + } + else { + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> shamt; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::ADD: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); + } catch(...){} + } + break; + case arch::traits::opcode_e::SUB: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); + } catch(...){} + } + break; + case arch::traits::opcode_e::SLL: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); + } catch(...){} + } + break; + case arch::traits::opcode_e::SLT: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; + } catch(...){} + } + break; + case arch::traits::opcode_e::SLTU: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; + } catch(...){} + } + break; + case arch::traits::opcode_e::XOR: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); + } catch(...){} + } + break; + case arch::traits::opcode_e::SRL: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); + } catch(...){} + } + break; + case arch::traits::opcode_e::SRA: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); + } catch(...){} + } + break; + case arch::traits::opcode_e::OR: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); + } catch(...){} + } + break; + case arch::traits::opcode_e::AND: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); + } catch(...){} + } + break; + case arch::traits::opcode_e::FENCE: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((bit_sub<24,4>(instr))); + uint8_t fm = ((bit_sub<28,4>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {pred}, {succ} ({fm} , {rs1}, {rd})", fmt::arg("mnemonic", "fence"), + fmt::arg("pred", pred), fmt::arg("succ", succ), fmt::arg("fm", fm), fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); + } catch(...){} + } + break; + case arch::traits::opcode_e::ECALL: { + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "ecall"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + raise(0, 11); + } catch(...){} + } + break; + case arch::traits::opcode_e::EBREAK: { + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "ebreak"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + raise(0, 3); + } catch(...){} + } + break; + case arch::traits::opcode_e::URET: { + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "uret"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + leave(0); + } catch(...){} + } + break; + case arch::traits::opcode_e::SRET: { + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "sret"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + leave(1); + } catch(...){} + } + break; + case arch::traits::opcode_e::MRET: { + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "mret"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + leave(3); + } catch(...){} + } + break; + case arch::traits::opcode_e::WFI: { + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "wfi"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + wait(1); + } catch(...){} + } + break; + case arch::traits::opcode_e::DRET: { + 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(...){} + } + break; + case arch::traits::opcode_e::CSRRW: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t xrs1 = *(X+rs1); + if(rd != 0) { + uint32_t xrd = readSpace4(traits::CSR, csr); + writeSpace4(traits::CSR, csr, xrs1); + *(X+rd) = xrd; + } + else { + writeSpace4(traits::CSR, csr, xrs1); + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CSRRS: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t xrd = readSpace4(traits::CSR, csr); + uint32_t xrs1 = *(X+rs1); + if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); + if(rd != 0) *(X+rd) = xrd; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CSRRC: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t xrd = readSpace4(traits::CSR, csr); + uint32_t xrs1 = *(X+rs1); + if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); + if(rd != 0) *(X+rd) = xrd; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CSRRWI: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t xrd = readSpace4(traits::CSR, csr); + writeSpace4(traits::CSR, csr, (uint32_t)zimm); + if(rd != 0) *(X+rd) = xrd; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CSRRSI: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t xrd = readSpace4(traits::CSR, csr); + if(zimm != 0) writeSpace4(traits::CSR, csr, xrd | (uint32_t)zimm); + if(rd != 0) *(X+rd) = xrd; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CSRRCI: { + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + uint32_t xrd = readSpace4(traits::CSR, csr); + if(zimm != 0) writeSpace4(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); + if(rd != 0) *(X+rd) = xrd; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::FENCE_I: { + 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(...){} + } + break; + case arch::traits::opcode_e::MUL: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(rd != 0) { + int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2); + *(X+rd) = (uint32_t)res; + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::MULH: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(rd != 0) { + int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2); + *(X+rd) = (uint32_t)(res >> traits::XLEN); + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::MULHSU: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(rd != 0) { + int64_t res = (int64_t)(int32_t)*(X+rs1) * (uint64_t)*(X+rs2); + *(X+rd) = (uint32_t)(res >> traits::XLEN); + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::MULHU: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(rd != 0) { + uint64_t res = (uint64_t)*(X+rs1) * (uint64_t)*(X+rs2); + *(X+rd) = (uint32_t)(res >> traits::XLEN); + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::DIV: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(rd != 0) { + if(*(X+rs2) != 0) { + uint32_t MMIN = 1 << (traits::XLEN - 1); + if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = MMIN; + else *(X+rd) = (int32_t)*(X+rs1) / (int32_t)*(X+rs2); + } + else *(X+rd) = - 1; + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::DIVU: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(rd != 0) { + if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) / *(X+rs2); + else *(X+rd) = - 1; + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::REM: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(rd != 0) { + if(*(X+rs2) != 0) { + uint32_t MMIN = 1 << (traits::XLEN - 1); + if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = 0; + else *(X+rd) = (int32_t)*(X+rs1) % (int32_t)*(X+rs2); + } + else *(X+rd) = *(X+rs1); + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::REMU: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + try { + { + if(rd != 0) { + if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) % *(X+rs2); + else *(X+rd) = *(X+rs1); + } + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CADDI4SPN: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "caddi4spn"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(imm) *(X+(rd + 8)) = *(X+2) + imm; + else raise(0, 2); + } catch(...){} + } + break; + case arch::traits::opcode_e::CLW: { + 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))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "clw"), + fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t load_address = *(X+(rs1 + 8)) + uimm; + *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CSW: { + 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))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "csw"), + fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t load_address = *(X+(rs1 + 8)) + uimm; + writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8))); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CADDI: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "caddi"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); + } catch(...){} + } + break; + case arch::traits::opcode_e::CNOP: { + 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 */ + this->core.disass_output(pc.val, "cnop"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CJAL: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cjal"), + fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + *(X+1) = *PC + 2; + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CLI: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "cli"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + if(rd != 0) *(X+rd) = (uint32_t)(int32_t)sext<6>(imm); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CLUI: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "clui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + if(imm == 0) raise(0, 2); + if(rd != 0) *(X+rd) = (int32_t)sext<18>(imm); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CADDI16SP: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {nzimm:#05x}", fmt::arg("mnemonic", "caddi16sp"), + fmt::arg("nzimm", nzimm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(nzimm) *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm); + else raise(0, 2); + } catch(...){} + } + break; + case arch::traits::opcode_e::__reserved_clui: { + 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(...){} + } + break; + case arch::traits::opcode_e::CSRLI: { + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrli"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = *(X+rs1_idx) >> shamt; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CSRAI: { + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrai"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(shamt) { + uint32_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt; + } + else if(traits::XLEN == 128) { + uint32_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CANDI: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "candi"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CSUB: { + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "csub"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8)); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CXOR: { + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cxor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8)); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::COR: { + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8)); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CAND: { + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cand"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8)); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CJ: { + 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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cj"), + fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); + } catch(...){} + } + break; + case arch::traits::opcode_e::CBEQZ: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbeqz"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); + } catch(...){} + } + break; + case arch::traits::opcode_e::CBNEZ: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbnez"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); + } catch(...){} + } + break; + case arch::traits::opcode_e::CSLLI: { + uint8_t nzuimm = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {nzuimm}", fmt::arg("mnemonic", "cslli"), + fmt::arg("rs1", name(rs1)), fmt::arg("nzuimm", nzuimm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; + } catch(...){} + } + break; + case arch::traits::opcode_e::CLWSP: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "clwsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(rd) { + uint32_t offs = *(X+2) + uimm; + *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); + } + else raise(0, 2); + } catch(...){} + } + break; + case arch::traits::opcode_e::CMV: { + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cmv"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rs2); + } catch(...){} + } + break; + case arch::traits::opcode_e::CJR: { + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjr"), + fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(rs1) pc_assign(*NEXT_PC) = *(X+rs1) & ~ 0x1; + else raise(0, 2); + } catch(...){} + } + break; + case arch::traits::opcode_e::__reserved_cmv: { + 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(...){} + } + break; + case arch::traits::opcode_e::CADD: { + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cadd"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); + } catch(...){} + } + break; + case arch::traits::opcode_e::CJALR: { + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjalr"), + fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + int32_t new_pc = *(X+rs1); + *(X+1) = *PC + 2; + pc_assign(*NEXT_PC) = new_pc & ~ 0x1; + } + } catch(...){} + } + break; + case arch::traits::opcode_e::CEBREAK: { + 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(...){} + } + break; + case arch::traits::opcode_e::CSWSP: { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "cswsp"), + fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); + this->core.disass_output(pc.val, mnemonic); + + } + // used registers + auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + { + uint32_t offs = *(X+2) + uimm; + writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); + } + } catch(...){} + } + break; + case arch::traits::opcode_e::DII: { + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "dii"); + + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + try { + raise(0, 2); + } catch(...){} + } + break; + default: { + *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2); + raise(0, 2); + } + } + // post execution stuff + process_spawn_blocks(); + 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); + } else { + (*icount)++; + (*instret)++; + } + (*reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::CYCLE]))++; + pc.val=*NEXT_PC; this->core.reg.PC = this->core.reg.NEXT_PC; this->core.reg.trap_state = this->core.reg.pending_trap; } @@ -4219,7 +2423,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co return pc; } -} // namespace mnrv32 +} template <> std::unique_ptr create(arch::tgc_c *core, unsigned short port, bool dump) { From 3d32c33333882f2db0098696efd560e837696f3b Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 5 Mar 2022 20:59:45 +0100 Subject: [PATCH 26/41] update gitignore --- gen_input/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/gen_input/.gitignore b/gen_input/.gitignore index b34c537..d1c585f 100644 --- a/gen_input/.gitignore +++ b/gen_input/.gitignore @@ -1 +1,2 @@ /src-gen/ +/CoreDSL-Instruction-Set-Description From 2e670c4d0300d2b17d3f0e62217873971554a65e Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 6 Mar 2022 15:11:38 +0100 Subject: [PATCH 27/41] change interpreter structure --- gen_input/templates/interp/CORENAME.cpp.gtl | 2 +- src/vm/interp/vm_tgc_c.cpp | 174 ++++++++++---------- 2 files changed, 88 insertions(+), 88 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 084bafd..98817ce 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -326,7 +326,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } // post execution stuff process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast(inst_id)); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 4f5f98d..9bbf941 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -397,7 +397,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (int32_t)imm; + if(rd != 0) *(X+rd) = (int32_t)imm; } catch(...){} } break; @@ -417,7 +417,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *PC + (int32_t)imm; + if(rd != 0) *(X+rd) = *PC + (int32_t)imm; } catch(...){} } break; @@ -439,10 +439,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + raise( 0, 0); } else { - if(rd != 0) *(X+rd) = *PC + 4; + if(rd != 0) *(X+rd) = *PC + 4; pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm); } } @@ -469,10 +469,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { int32_t new_pc = (*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 1; if(new_pc % traits::INSTR_ALIGNMENT) { - raise(0, 0); + raise( 0, 0); } else { - if(rd != 0) *(X+rd) = *PC + 4; + if(rd != 0) *(X+rd) = *PC + 4; pc_assign(*NEXT_PC) = new_pc & ~ 0x1; } } @@ -498,7 +498,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if(*(X+rs1) == *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + raise( 0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -526,7 +526,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if(*(X+rs1) != *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + raise( 0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -554,7 +554,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + raise( 0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -582,7 +582,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + raise( 0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -610,7 +610,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if(*(X+rs1) < *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + raise( 0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -638,7 +638,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if(*(X+rs1) >= *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); + raise( 0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -666,7 +666,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); - if(rd != 0) *(X+rd) = res; + if(rd != 0) *(X+rd) = res; } } catch(...){} } @@ -691,7 +691,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); int16_t res = (int16_t)readSpace2(traits::MEM, load_address); - if(rd != 0) *(X+rd) = res; + if(rd != 0) *(X+rd) = res; } } catch(...){} } @@ -716,7 +716,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); int32_t res = (int32_t)readSpace4(traits::MEM, load_address); - if(rd != 0) *(X+rd) = (uint32_t)res; + if(rd != 0) *(X+rd) = (uint32_t)res; } } catch(...){} } @@ -740,7 +740,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); - if(rd != 0) *(X+rd) = res; + if(rd != 0) *(X+rd) = res; } } catch(...){} } @@ -765,7 +765,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); uint16_t res = (uint16_t)readSpace2(traits::MEM, load_address); - if(rd != 0) *(X+rd) = res; + if(rd != 0) *(X+rd) = res; } } catch(...){} } @@ -856,7 +856,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); + if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); } catch(...){} } break; @@ -877,7 +877,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; } catch(...){} } break; @@ -898,7 +898,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; + if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; } catch(...){} } break; @@ -919,7 +919,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); + if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); } catch(...){} } break; @@ -940,7 +940,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); + if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); } catch(...){} } break; @@ -961,7 +961,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); + if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); } catch(...){} } break; @@ -983,10 +983,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(shamt > 31) { - raise(0, 0); + raise( 0, 0); } else { - if(rd != 0) *(X+rd) = *(X+rs1) << shamt; + if(rd != 0) *(X+rd) = *(X+rs1) << shamt; } } catch(...){} } @@ -1009,10 +1009,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(shamt > 31) { - raise(0, 0); + raise( 0, 0); } else { - if(rd != 0) *(X+rd) = *(X+rs1) >> shamt; + if(rd != 0) *(X+rd) = *(X+rs1) >> shamt; } } catch(...){} } @@ -1035,10 +1035,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(shamt > 31) { - raise(0, 0); + raise( 0, 0); } else { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> shamt; + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> shamt; } } catch(...){} } @@ -1060,7 +1060,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); + if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); } catch(...){} } break; @@ -1081,7 +1081,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); + if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); } catch(...){} } break; @@ -1102,7 +1102,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); + if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} } break; @@ -1123,7 +1123,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; } catch(...){} } break; @@ -1144,7 +1144,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; + if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; } catch(...){} } break; @@ -1165,7 +1165,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); + if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); } catch(...){} } break; @@ -1186,7 +1186,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); + if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} } break; @@ -1207,7 +1207,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); + if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); } catch(...){} } break; @@ -1228,7 +1228,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); + if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); } catch(...){} } break; @@ -1249,7 +1249,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); + if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); } catch(...){} } break; @@ -1285,7 +1285,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - raise(0, 11); + raise( 0, 11); } catch(...){} } break; @@ -1299,7 +1299,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - raise(0, 3); + raise( 0, 3); } catch(...){} } break; @@ -1313,7 +1313,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - leave(0); + leave( 0); } catch(...){} } break; @@ -1327,7 +1327,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - leave(1); + leave( 1); } catch(...){} } break; @@ -1341,7 +1341,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - leave(3); + leave( 3); } catch(...){} } break; @@ -1355,7 +1355,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - wait(1); + wait( 1); } catch(...){} } break; @@ -1374,7 +1374,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(*PRIV < 4) raise(0, 2); + if(*PRIV < 4) raise( 0, 2); else { pc_assign(*NEXT_PC) = *DPC; *PRIV &= 0x3; @@ -1434,8 +1434,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t xrd = readSpace4(traits::CSR, csr); uint32_t xrs1 = *(X+rs1); - if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); - if(rd != 0) *(X+rd) = xrd; + if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); + if(rd != 0) *(X+rd) = xrd; } } catch(...){} } @@ -1460,8 +1460,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t xrd = readSpace4(traits::CSR, csr); uint32_t xrs1 = *(X+rs1); - if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); - if(rd != 0) *(X+rd) = xrd; + if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); + if(rd != 0) *(X+rd) = xrd; } } catch(...){} } @@ -1486,7 +1486,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t xrd = readSpace4(traits::CSR, csr); writeSpace4(traits::CSR, csr, (uint32_t)zimm); - if(rd != 0) *(X+rd) = xrd; + if(rd != 0) *(X+rd) = xrd; } } catch(...){} } @@ -1510,8 +1510,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t xrd = readSpace4(traits::CSR, csr); - if(zimm != 0) writeSpace4(traits::CSR, csr, xrd | (uint32_t)zimm); - if(rd != 0) *(X+rd) = xrd; + if(zimm != 0) writeSpace4(traits::CSR, csr, xrd | (uint32_t)zimm); + if(rd != 0) *(X+rd) = xrd; } } catch(...){} } @@ -1535,8 +1535,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t xrd = readSpace4(traits::CSR, csr); - if(zimm != 0) writeSpace4(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); - if(rd != 0) *(X+rd) = xrd; + if(zimm != 0) writeSpace4(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); + if(rd != 0) *(X+rd) = xrd; } } catch(...){} } @@ -1686,7 +1686,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co if(rd != 0) { if(*(X+rs2) != 0) { uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = MMIN; + if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = MMIN; else *(X+rd) = (int32_t)*(X+rs1) / (int32_t)*(X+rs2); } else *(X+rd) = - 1; @@ -1714,7 +1714,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if(rd != 0) { - if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) / *(X+rs2); + if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) / *(X+rs2); else *(X+rd) = - 1; } } @@ -1742,7 +1742,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co if(rd != 0) { if(*(X+rs2) != 0) { uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = 0; + if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = 0; else *(X+rd) = (int32_t)*(X+rs1) % (int32_t)*(X+rs2); } else *(X+rd) = *(X+rs1); @@ -1770,7 +1770,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if(rd != 0) { - if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) % *(X+rs2); + if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) % *(X+rs2); else *(X+rd) = *(X+rs1); } } @@ -1793,8 +1793,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(imm) *(X+(rd + 8)) = *(X+2) + imm; - else raise(0, 2); + if(imm) *(X+rd + 8) = *(X+2) + imm; + else raise( 0, 2); } catch(...){} } break; @@ -1816,8 +1816,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t load_address = *(X+(rs1 + 8)) + uimm; - *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, load_address); + uint32_t load_address = *(X+rs1 + 8) + uimm; + *(X+rd + 8) = (int32_t)readSpace4(traits::MEM, load_address); } } catch(...){} } @@ -1840,8 +1840,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t load_address = *(X+(rs1 + 8)) + uimm; - writeSpace4(traits::MEM, load_address, *(X+(rs2 + 8))); + uint32_t load_address = *(X+rs1 + 8) + uimm; + writeSpace4(traits::MEM, load_address, *(X+rs2 + 8)); } } catch(...){} } @@ -1921,7 +1921,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) *(X+rd) = (uint32_t)(int32_t)sext<6>(imm); + if(rd != 0) *(X+rd) = (uint32_t)(int32_t)sext<6>(imm); } } catch(...){} } @@ -1943,8 +1943,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(imm == 0) raise(0, 2); - if(rd != 0) *(X+rd) = (int32_t)sext<18>(imm); + if(imm == 0) raise( 0, 2); + if(rd != 0) *(X+rd) = (int32_t)sext<18>(imm); } } catch(...){} } @@ -1964,8 +1964,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(nzimm) *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm); - else raise(0, 2); + if(nzimm) *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm); + else raise( 0, 2); } catch(...){} } break; @@ -1980,7 +1980,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - raise(0, 2); + raise( 0, 2); } catch(...){} } break; @@ -2075,7 +2075,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8)); + *(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8); } } catch(...){} } @@ -2098,7 +2098,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8)); + *(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8); } } catch(...){} } @@ -2121,7 +2121,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8)); + *(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8); } } catch(...){} } @@ -2144,7 +2144,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8)); + *(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8); } } catch(...){} } @@ -2183,7 +2183,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); + if(*(X+rs1 + 8) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} } break; @@ -2203,7 +2203,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); + if(*(X+rs1 + 8) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); } catch(...){} } break; @@ -2223,7 +2223,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; + if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; } catch(...){} } break; @@ -2247,7 +2247,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co uint32_t offs = *(X+2) + uimm; *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); } - else raise(0, 2); + else raise( 0, 2); } catch(...){} } break; @@ -2267,7 +2267,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs2); + if(rd != 0) *(X+rd) = *(X+rs2); } catch(...){} } break; @@ -2286,8 +2286,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(rs1) pc_assign(*NEXT_PC) = *(X+rs1) & ~ 0x1; - else raise(0, 2); + if(rs1) pc_assign(*NEXT_PC) = *(X+rs1) & ~ 0x1; + else raise( 0, 2); } catch(...){} } break; @@ -2301,7 +2301,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - raise(0, 2); + raise( 0, 2); } catch(...){} } break; @@ -2321,7 +2321,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); + if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); } catch(...){} } break; @@ -2358,7 +2358,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - raise(0, 3); + raise( 0, 3); } catch(...){} } break; @@ -2395,7 +2395,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - raise(0, 2); + raise( 0, 2); } catch(...){} } break; @@ -2406,7 +2406,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } // post execution stuff process_spawn_blocks(); - if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast(inst_id)); // trap check if(*trap_state!=0){ super::core.enter_trap(*trap_state, pc.val, instr); From 5ec457c76b1ca3d4ce657ae5ffa534595a846b5c Mon Sep 17 00:00:00 2001 From: Stanislaw Kaushanski Date: Tue, 8 Mar 2022 11:23:07 +0100 Subject: [PATCH 28/41] build pctrace plugin only if RapidJSON target is availble --- CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fa3d9b..64f83ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(dbt-rise-tgc VERSION 1.0.0) include(GNUInstallDirs) -find_package(elfio) +find_package(elfio QUIET) find_package(Boost COMPONENTS coroutine) if(WITH_LLVM) @@ -35,13 +35,12 @@ FILE(GLOB TGC_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp) set(LIB_SOURCES src/vm/fp_functions.cpp src/plugin/instruction_count.cpp - src/plugin/pctrace.cpp ${TGC_SOURCES} ${TGC_VM_SOURCES} ) if(TARGET RapidJSON) - list(APPEND LIB_SOURCES src/plugin/cycle_estimate.cpp) + list(APPEND LIB_SOURCES src/plugin/cycle_estimate.cpp src/plugin/pctrace.cpp) endif() if(WITH_LLVM) From d91f5f9df42779bcb4ce6f5ae95b6e1096c89e25 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 14 Mar 2022 15:37:01 +0100 Subject: [PATCH 29/41] fix compiler warning for reduced number of registers --- incl/iss/arch/tgc_c.h | 2 +- incl/iss/debugger/riscv_target_adapter.h | 24 ++- src/vm/interp/vm_tgc_c.cpp | 240 +++++++++++------------ 3 files changed, 140 insertions(+), 126 deletions(-) diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index c9528bb..74ab760 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", "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}; + enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, RFS=32, XLEN=32, CSR_SIZE=4096, INSTR_ALIGNMENT=2, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; constexpr static unsigned FP_REGS_SIZE = 0; diff --git a/incl/iss/debugger/riscv_target_adapter.h b/incl/iss/debugger/riscv_target_adapter.h index f134364..b7c3036 100644 --- a/incl/iss/debugger/riscv_target_adapter.h +++ b/incl/iss/debugger/riscv_target_adapter.h @@ -214,12 +214,26 @@ template status riscv_target_adapter::write_registers(cons auto start_reg=arch::traits::X0; auto *reg_base = core->get_regs_base_ptr(); auto iter = data.data(); + bool e_ext = arch::traits::PC<32; for (size_t reg_no = 0; reg_no < start_reg+33/*arch::traits::NUM_REGS*/; ++reg_no) { - auto reg_width = arch::traits::reg_bit_widths[reg_no] / 8; - auto offset = traits::reg_byte_offsets[reg_no]; - std::copy(iter, iter + reg_width, reg_base); - iter += 4; - reg_base += offset; + if(e_ext && reg_no>15){ + if(reg_no==32){ + auto reg_width = arch::traits::reg_bit_widths[arch::traits::PC] / 8; + auto offset = traits::reg_byte_offsets[arch::traits::PC]; + std::copy(iter, iter + reg_width, reg_base); + } else { + const uint64_t zero_val=0; + auto reg_width = arch::traits::reg_bit_widths[15] / 8; + auto iter = (uint8_t*)&zero_val; + std::copy(iter, iter + reg_width, reg_base); + } + } else { + auto reg_width = arch::traits::reg_bit_widths[reg_no] / 8; + auto offset = traits::reg_byte_offsets[reg_no]; + std::copy(iter, iter + reg_width, reg_base); + iter += 4; + reg_base += offset; + } } return Ok; } diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 9bbf941..52fd588 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -397,7 +397,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (int32_t)imm; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)imm; } catch(...){} } break; @@ -417,7 +417,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *PC + (int32_t)imm; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *PC + (int32_t)imm; } catch(...){} } break; @@ -439,10 +439,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { if(imm % traits::INSTR_ALIGNMENT) { - raise( 0, 0); + raise(0, 0); } else { - if(rd != 0) *(X+rd) = *PC + 4; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *PC + 4; pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm); } } @@ -467,12 +467,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - int32_t new_pc = (*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 1; + int32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 1; if(new_pc % traits::INSTR_ALIGNMENT) { - raise( 0, 0); + raise(0, 0); } else { - if(rd != 0) *(X+rd) = *PC + 4; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *PC + 4; pc_assign(*NEXT_PC) = new_pc & ~ 0x1; } } @@ -497,8 +497,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(*(X+rs1) == *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise( 0, 0); + if(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -525,8 +525,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(*(X+rs1) != *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise( 0, 0); + if(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -553,8 +553,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise( 0, 0); + if((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -581,8 +581,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise( 0, 0); + if((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -609,8 +609,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(*(X+rs1) < *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise( 0, 0); + if(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -637,8 +637,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(*(X+rs1) >= *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) { - raise( 0, 0); + if(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); } else { pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); @@ -665,8 +665,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); - if(rd != 0) *(X+rd) = res; + int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = res; } } catch(...){} } @@ -689,9 +689,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); + uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); int16_t res = (int16_t)readSpace2(traits::MEM, load_address); - if(rd != 0) *(X+rd) = res; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = res; } } catch(...){} } @@ -714,9 +714,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); + uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); int32_t res = (int32_t)readSpace4(traits::MEM, load_address); - if(rd != 0) *(X+rd) = (uint32_t)res; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (uint32_t)res; } } catch(...){} } @@ -739,8 +739,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm)); - if(rd != 0) *(X+rd) = res; + uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = res; } } catch(...){} } @@ -763,9 +763,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); + uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); uint16_t res = (uint16_t)readSpace2(traits::MEM, load_address); - if(rd != 0) *(X+rd) = res; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = res; } } catch(...){} } @@ -787,7 +787,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - writeSpace1(traits::MEM, *(X+rs1) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2)); + writeSpace1(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2 % traits::RFS)); } catch(...){} } break; @@ -809,8 +809,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); - writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2)); + uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); + writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2 % traits::RFS)); } } catch(...){} } @@ -833,8 +833,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); - writeSpace4(traits::MEM, store_address, *(X+rs2)); + uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); + writeSpace4(traits::MEM, store_address, *(X+rs2 % traits::RFS)); } } catch(...){} } @@ -856,7 +856,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); } catch(...){} } break; @@ -877,7 +877,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int16_t)sext<12>(imm)? 1 : 0; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm)? 1 : 0; } catch(...){} } break; @@ -898,7 +898,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (*(X+rs1) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (*(X+rs1 % traits::RFS) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; } catch(...){} } break; @@ -919,7 +919,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) ^ (int16_t)sext<12>(imm); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ (int16_t)sext<12>(imm); } catch(...){} } break; @@ -940,7 +940,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) | (int16_t)sext<12>(imm); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | (int16_t)sext<12>(imm); } catch(...){} } break; @@ -961,7 +961,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) & (int16_t)sext<12>(imm); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & (int16_t)sext<12>(imm); } catch(...){} } break; @@ -983,10 +983,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(shamt > 31) { - raise( 0, 0); + raise(0, 0); } else { - if(rd != 0) *(X+rd) = *(X+rs1) << shamt; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt; } } catch(...){} } @@ -1009,10 +1009,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(shamt > 31) { - raise( 0, 0); + raise(0, 0); } else { - if(rd != 0) *(X+rd) = *(X+rs1) >> shamt; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt; } } catch(...){} } @@ -1035,10 +1035,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(shamt > 31) { - raise( 0, 0); + raise(0, 0); } else { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> shamt; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt; } } catch(...){} } @@ -1060,7 +1060,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + *(X+rs2 % traits::RFS); } catch(...){} } break; @@ -1081,7 +1081,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) - *(X+rs2 % traits::RFS); } catch(...){} } break; @@ -1102,7 +1102,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); } catch(...){} } break; @@ -1123,7 +1123,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) < (int32_t)*(X+rs2)? 1 : 0; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)? 1 : 0; } catch(...){} } break; @@ -1144,7 +1144,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (uint32_t)*(X+rs1 % traits::RFS) < (uint32_t)*(X+rs2 % traits::RFS)? 1 : 0; } catch(...){} } break; @@ -1165,7 +1165,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ *(X+rs2 % traits::RFS); } catch(...){} } break; @@ -1186,7 +1186,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); } catch(...){} } break; @@ -1207,7 +1207,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); } catch(...){} } break; @@ -1228,7 +1228,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | *(X+rs2 % traits::RFS); } catch(...){} } break; @@ -1249,7 +1249,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & *(X+rs2 % traits::RFS); } catch(...){} } break; @@ -1285,7 +1285,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - raise( 0, 11); + raise(0, 11); } catch(...){} } break; @@ -1299,7 +1299,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - raise( 0, 3); + raise(0, 3); } catch(...){} } break; @@ -1313,7 +1313,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - leave( 0); + leave(0); } catch(...){} } break; @@ -1327,7 +1327,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - leave( 1); + leave(1); } catch(...){} } break; @@ -1341,7 +1341,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - leave( 3); + leave(3); } catch(...){} } break; @@ -1355,7 +1355,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction try { - wait( 1); + wait(1); } catch(...){} } break; @@ -1374,7 +1374,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(*PRIV < 4) raise( 0, 2); + if(*PRIV < 4) raise(0, 2); else { pc_assign(*NEXT_PC) = *DPC; *PRIV &= 0x3; @@ -1401,11 +1401,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t xrs1 = *(X+rs1); - if(rd != 0) { + uint32_t xrs1 = *(X+rs1 % traits::RFS); + if((rd % traits::RFS) != 0) { uint32_t xrd = readSpace4(traits::CSR, csr); writeSpace4(traits::CSR, csr, xrs1); - *(X+rd) = xrd; + *(X+rd % traits::RFS) = xrd; } else { writeSpace4(traits::CSR, csr, xrs1); @@ -1433,9 +1433,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t xrd = readSpace4(traits::CSR, csr); - uint32_t xrs1 = *(X+rs1); + uint32_t xrs1 = *(X+rs1 % traits::RFS); if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); - if(rd != 0) *(X+rd) = xrd; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; } } catch(...){} } @@ -1459,9 +1459,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t xrd = readSpace4(traits::CSR, csr); - uint32_t xrs1 = *(X+rs1); + uint32_t xrs1 = *(X+rs1 % traits::RFS); if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); - if(rd != 0) *(X+rd) = xrd; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; } } catch(...){} } @@ -1486,7 +1486,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t xrd = readSpace4(traits::CSR, csr); writeSpace4(traits::CSR, csr, (uint32_t)zimm); - if(rd != 0) *(X+rd) = xrd; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; } } catch(...){} } @@ -1511,7 +1511,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t xrd = readSpace4(traits::CSR, csr); if(zimm != 0) writeSpace4(traits::CSR, csr, xrd | (uint32_t)zimm); - if(rd != 0) *(X+rd) = xrd; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; } } catch(...){} } @@ -1536,7 +1536,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t xrd = readSpace4(traits::CSR, csr); if(zimm != 0) writeSpace4(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); - if(rd != 0) *(X+rd) = xrd; + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; } } catch(...){} } @@ -1579,9 +1579,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) { - int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2); - *(X+rd) = (uint32_t)res; + if((rd % traits::RFS) != 0) { + int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (int64_t)(int32_t)*(X+rs2 % traits::RFS); + *(X+rd % traits::RFS) = (uint32_t)res; } } } catch(...){} @@ -1605,9 +1605,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) { - int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2); - *(X+rd) = (uint32_t)(res >> traits::XLEN); + if((rd % traits::RFS) != 0) { + int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (int64_t)(int32_t)*(X+rs2 % traits::RFS); + *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); } } } catch(...){} @@ -1631,9 +1631,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) { - int64_t res = (int64_t)(int32_t)*(X+rs1) * (uint64_t)*(X+rs2); - *(X+rd) = (uint32_t)(res >> traits::XLEN); + if((rd % traits::RFS) != 0) { + int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (uint64_t)*(X+rs2 % traits::RFS); + *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); } } } catch(...){} @@ -1657,9 +1657,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) { - uint64_t res = (uint64_t)*(X+rs1) * (uint64_t)*(X+rs2); - *(X+rd) = (uint32_t)(res >> traits::XLEN); + if((rd % traits::RFS) != 0) { + uint64_t res = (uint64_t)*(X+rs1 % traits::RFS) * (uint64_t)*(X+rs2 % traits::RFS); + *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); } } } catch(...){} @@ -1683,13 +1683,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) { - if(*(X+rs2) != 0) { + if((rd % traits::RFS) != 0) { + if(*(X+rs2 % traits::RFS) != 0) { uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = MMIN; - else *(X+rd) = (int32_t)*(X+rs1) / (int32_t)*(X+rs2); + if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) *(X+rd % traits::RFS) = MMIN; + else *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) / (int32_t)*(X+rs2 % traits::RFS); } - else *(X+rd) = - 1; + else *(X+rd % traits::RFS) = - 1; } } } catch(...){} @@ -1713,9 +1713,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) { - if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) / *(X+rs2); - else *(X+rd) = - 1; + if((rd % traits::RFS) != 0) { + if(*(X+rs2 % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) / *(X+rs2 % traits::RFS); + else *(X+rd % traits::RFS) = - 1; } } } catch(...){} @@ -1739,13 +1739,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) { - if(*(X+rs2) != 0) { + if((rd % traits::RFS) != 0) { + if(*(X+rs2 % traits::RFS) != 0) { uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) *(X+rd) = 0; - else *(X+rd) = (int32_t)*(X+rs1) % (int32_t)*(X+rs2); + if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) *(X+rd % traits::RFS) = 0; + else *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) % (int32_t)*(X+rs2 % traits::RFS); } - else *(X+rd) = *(X+rs1); + else *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); } } } catch(...){} @@ -1769,9 +1769,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) { - if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) % *(X+rs2); - else *(X+rd) = *(X+rs1); + if((rd % traits::RFS) != 0) { + if(*(X+rs2 % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) % *(X+rs2 % traits::RFS); + else *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); } } } catch(...){} @@ -1794,7 +1794,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(imm) *(X+rd + 8) = *(X+2) + imm; - else raise( 0, 2); + else raise(0, 2); } catch(...){} } break; @@ -1862,7 +1862,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); + *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) + (int8_t)sext<6>(imm); } catch(...){} } break; @@ -1921,7 +1921,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(rd != 0) *(X+rd) = (uint32_t)(int32_t)sext<6>(imm); + if((rd % traits::RFS) != 0) *(X+rd) = (uint32_t)(int32_t)sext<6>(imm); } } catch(...){} } @@ -1943,8 +1943,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - if(imm == 0) raise( 0, 2); - if(rd != 0) *(X+rd) = (int32_t)sext<18>(imm); + if(imm == 0) raise(0, 2); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)sext<18>(imm); } } catch(...){} } @@ -1965,7 +1965,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(nzimm) *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm); - else raise( 0, 2); + else raise(0, 2); } catch(...){} } break; @@ -1980,7 +1980,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - raise( 0, 2); + raise(0, 2); } catch(...){} } break; @@ -2223,7 +2223,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(nzuimm) *(X+rs1) = *(X+rs1) << nzuimm; + if(nzuimm) *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) << nzuimm; } catch(...){} } break; @@ -2245,9 +2245,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { if(rd) { uint32_t offs = *(X+2) + uimm; - *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); + *(X+rd % traits::RFS) = (int32_t)readSpace4(traits::MEM, offs); } - else raise( 0, 2); + else raise(0, 2); } catch(...){} } break; @@ -2267,7 +2267,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rs2); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs2 % traits::RFS); } catch(...){} } break; @@ -2286,8 +2286,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(rs1) pc_assign(*NEXT_PC) = *(X+rs1) & ~ 0x1; - else raise( 0, 2); + if(rs1) pc_assign(*NEXT_PC) = *(X+rs1 % traits::RFS) & ~ 0x1; + else raise(0, 2); } catch(...){} } break; @@ -2301,7 +2301,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - raise( 0, 2); + raise(0, 2); } catch(...){} } break; @@ -2321,7 +2321,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - if(rd != 0) *(X+rd) = *(X+rd) + *(X+rs2); + if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rd % traits::RFS) + *(X+rs2 % traits::RFS); } catch(...){} } break; @@ -2341,7 +2341,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - int32_t new_pc = *(X+rs1); + int32_t new_pc = *(X+rs1 % traits::RFS); *(X+1) = *PC + 2; pc_assign(*NEXT_PC) = new_pc & ~ 0x1; } @@ -2358,7 +2358,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - raise( 0, 3); + raise(0, 3); } catch(...){} } break; @@ -2380,7 +2380,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co try { { uint32_t offs = *(X+2) + uimm; - writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); + writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2 % traits::RFS)); } } catch(...){} } @@ -2395,7 +2395,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction try { - raise( 0, 2); + raise(0, 2); } catch(...){} } break; From 30ae7433611084d85148adbbad199f4f54773166 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 20 Mar 2022 17:39:44 +0100 Subject: [PATCH 30/41] add pctrace plugin to iss --- src/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 88c9812..3071b73 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,6 +75,7 @@ using tgc_e_plat_type = iss::arch::riscv_hart_mu_p #include #include +#include #include #if defined(HAS_LUA) #include @@ -208,7 +209,11 @@ int main(int argc, char *argv[]) { auto *ce_plugin = new iss::plugin::cycle_estimate(filename); vm->register_plugin(*ce_plugin); plugin_list.push_back(ce_plugin); - } else { + } else if (plugin_name == "pctrace") { + auto *plugin = new iss::plugin::cov(filename); + 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()); From 9dfca612b7491ee18695714c26b0df02abdd3981 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 25 Mar 2022 11:33:44 +0100 Subject: [PATCH 31/41] add hardware loop CSR access --- incl/iss/arch/hwl.h | 100 ++++++++++++++++++++++++++++++ incl/iss/arch/riscv_hart_m_p.h | 10 +++ incl/iss/arch/riscv_hart_msu_vp.h | 10 +++ incl/iss/arch/riscv_hart_mu_p.h | 10 +++ 4 files changed, 130 insertions(+) create mode 100644 incl/iss/arch/hwl.h diff --git a/incl/iss/arch/hwl.h b/incl/iss/arch/hwl.h new file mode 100644 index 0000000..9e954ba --- /dev/null +++ b/incl/iss/arch/hwl.h @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (C) 2022 MINRES Technologies GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Contributors: + * eyck@minres.com - initial implementation + ******************************************************************************/ + +#ifndef _RISCV_HART_M_P_HWL_H +#define _RISCV_HART_M_P_HWL_H + +#include + +namespace iss { +namespace arch { + +template class hwl : public BASE { +public: + using base_class = BASE; + using this_class = hwl; + using reg_t = typename BASE::reg_t; + + hwl(); + virtual ~hwl() = default; + +protected: + iss::status read_custom_csr_reg(unsigned addr, reg_t &val) override; + iss::status write_custom_csr_reg(unsigned addr, reg_t val) override; +}; + + +template +inline hwl::hwl() { + for (unsigned addr = 0x800; addr < 0x803; ++addr){ + this->register_custom_csr_rd(addr); + this->register_custom_csr_wr(addr); + } + for (unsigned addr = 0x804; addr < 0x807; ++addr){ + this->register_custom_csr_rd(addr); + this->register_custom_csr_wr(addr); + } +} + +template +inline iss::status iss::arch::hwl::read_custom_csr_reg(unsigned addr, reg_t &val) { + switch(addr){ + case 0x800: val = this->reg.lpstart0; break; + case 0x801: val = this->reg.lpend0; break; + case 0x802: val = this->reg.lpcount0; break; + case 0x804: val = this->reg.lpstart1; break; + case 0x805: val = this->reg.lpend1; break; + case 0x806: val = this->reg.lpcount1; break; + } + return iss::Ok; +} + +template +inline iss::status iss::arch::hwl::write_custom_csr_reg(unsigned addr, reg_t val) { + switch(addr){ + case 0x800: this->reg.lpstart0 = val; break; + case 0x801: this->reg.lpend0 = val; break; + case 0x802: this->reg.lpcount0 = val; break; + case 0x804: this->reg.lpstart1 = val; break; + case 0x805: this->reg.lpend1 = val; break; + case 0x806: this->reg.lpcount1 = val; break; + } + return iss::Ok; +} + +} // namespace arch +} // namespace iss + + +#endif /* _RISCV_HART_M_P_H */ diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 91dd7b4..b55625c 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -321,6 +321,16 @@ protected: iss::status read_dpc_reg(unsigned addr, reg_t &val); iss::status write_dpc_reg(unsigned addr, reg_t val); + virtual iss::status read_custom_csr_reg(unsigned addr, reg_t &val) {return iss::status::Err;}; + virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) {return iss::status::Err;}; + + void register_custom_csr_rd(unsigned addr){ + csr_rd_cb[addr] = &this_class::read_custom_csr_reg; + } + void register_custom_csr_wr(unsigned addr){ + csr_wr_cb[addr] = &this_class::write_custom_csr_reg; + } + reg_t mhartid_reg{0x0}; std::functionmem_read_cb; std::function mem_write_cb; diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index 4ba669e..853a4bf 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -408,6 +408,16 @@ private: iss::status read_fcsr(unsigned addr, reg_t &val); iss::status write_fcsr(unsigned addr, reg_t val); + virtual iss::status read_custom_csr_reg(unsigned addr, reg_t &val) {return iss::status::Err;}; + virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) {return iss::status::Err;}; + + void register_custom_csr_rd(unsigned addr){ + csr_rd_cb[addr] = &this_class::read_custom_csr_reg; + } + void register_custom_csr_wr(unsigned addr){ + csr_wr_cb[addr] = &this_class::write_custom_csr_reg; + } + reg_t mhartid_reg{0x0}; std::functionmem_read_cb; std::function mem_write_cb; diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index ab0444c..aafd204 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -339,6 +339,16 @@ protected: iss::status write_dpc_reg(unsigned addr, reg_t val); iss::status write_pmpcfg_reg(unsigned addr, reg_t val); + virtual iss::status read_custom_csr_reg(unsigned addr, reg_t &val) {return iss::status::Err;}; + virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) {return iss::status::Err;}; + + void register_custom_csr_rd(unsigned addr){ + csr_rd_cb[addr] = &this_class::read_custom_csr_reg; + } + void register_custom_csr_wr(unsigned addr){ + csr_wr_cb[addr] = &this_class::write_custom_csr_reg; + } + reg_t mhartid_reg{0x0}; std::functionmem_read_cb; std::function mem_write_cb; From b0cb997009b0f234269c394706dd5c8a2698c4d2 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 26 Mar 2022 10:48:21 +0100 Subject: [PATCH 32/41] add TGC_X with DMR --- incl/iss/arch/tgc_mapper.h | 43 ++++++++++++++++++++++++++++++++++++++ src/main.cpp | 35 +------------------------------ src/sysc/core_complex.cpp | 38 +++++++-------------------------- 3 files changed, 52 insertions(+), 64 deletions(-) create mode 100644 incl/iss/arch/tgc_mapper.h diff --git a/incl/iss/arch/tgc_mapper.h b/incl/iss/arch/tgc_mapper.h new file mode 100644 index 0000000..1d4dd73 --- /dev/null +++ b/incl/iss/arch/tgc_mapper.h @@ -0,0 +1,43 @@ +#ifndef _ISS_ARCH_TGC_MAPPER_H +#define _ISS_ARCH_TGC_MAPPER_H + +#include "riscv_hart_m_p.h" +#include "tgc_c.h" +using tgc_c_plat_type = iss::arch::riscv_hart_m_p; +#ifdef CORE_TGC_B +#include "riscv_hart_m_p.h" +#include "tgc_b.h" +using tgc_b_plat_type = iss::arch::riscv_hart_m_p; +#endif +#ifdef CORE_TGC_C_XRB_NN +#include "riscv_hart_m_p.h" +#include "tgc_c_xrb_nn.h" +using tgc_c_xrb_nn_plat_type = iss::arch::riscv_hart_m_p; +#endif +#ifdef CORE_TGC_D +#include "riscv_hart_mu_p.h" +#include "tgc_d.h" +using tgc_d_plat_type = iss::arch::riscv_hart_mu_p; +#endif +#ifdef CORE_TGC_D_XRB_MAC +#include "riscv_hart_mu_p.h" +#include "tgc_d_xrb_mac.h" +using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p; +#endif +#ifdef CORE_TGC_D_XRB_NN +#include "riscv_hart_mu_p.h" +#include "tgc_d_xrb_nn.h" +using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p; +#endif +#ifdef CORE_TGC_E +#include "riscv_hart_mu_p.h" +#include "tgc_e.h" +using tgc_e_plat_type = iss::arch::riscv_hart_mu_p; +#endif +#ifdef CORE_TGC_X +#include "riscv_hart_mu_p.h" +#include "tgc_x.h" +using tgc_x_plat_type = iss::arch::riscv_hart_mu_p; +#endif + +#endif diff --git a/src/main.cpp b/src/main.cpp index 3071b73..bbde374 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,40 +35,7 @@ #include #include -#include -#include "iss/arch/riscv_hart_m_p.h" -#include "iss/arch/tgc_c.h" -using tgc_c_plat_type = iss::arch::riscv_hart_m_p; -#ifdef CORE_TGC_B -#include "iss/arch/riscv_hart_m_p.h" -#include "iss/arch/tgc_b.h" -using tgc_b_plat_type = iss::arch::riscv_hart_m_p; -#endif -#ifdef CORE_TGC_C_XRB_NN -#include "iss/arch/riscv_hart_m_p.h" -#include "iss/arch/tgc_c_xrb_nn.h" -using tgc_c_xrb_nn_plat_type = iss::arch::riscv_hart_m_p; -#endif -#ifdef CORE_TGC_D -#include "iss/arch/riscv_hart_mu_p.h" -#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 CORE_TGC_D_XRB_NN -#include "iss/arch/riscv_hart_mu_p.h" -#include "iss/arch/tgc_d_xrb_nn.h" -using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p; -#endif -#ifdef CORE_TGC_E -#include "iss/arch/riscv_hart_mu_p.h" -#include "iss/arch/tgc_e.h" -using tgc_e_plat_type = iss::arch::riscv_hart_mu_p; -#endif +#include #ifdef WITH_LLVM #include #endif diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 23ab3e5..3d29ee8 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -31,37 +31,15 @@ *******************************************************************************/ // clang-format off -#include "iss/debugger/gdb_session.h" -#include "iss/debugger/encoderdecoder.h" -#include "iss/debugger/server.h" -#include "iss/debugger/target_adapter_if.h" -#include "iss/iss.h" -#include "iss/vm_types.h" +#include +#include +#include +#include +#include +#include #include -#include "sysc/core_complex.h" -#ifdef CORE_TGC_B -#include "iss/arch/riscv_hart_m_p.h" -#include "iss/arch/tgc_b.h" -using tgc_b_plat_type = iss::arch::riscv_hart_m_p; -#endif -#include "iss/arch/riscv_hart_m_p.h" -#include "iss/arch/tgc_c.h" -using tgc_c_plat_type = iss::arch::riscv_hart_m_p; -#ifdef CORE_TGC_D -#include "iss/arch/riscv_hart_mu_p.h" -#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 CORE_TGC_D_XRB_NN -#include "iss/arch/riscv_hart_mu_p.h" -#include "iss/arch/tgc_d_xrb_nn.h" -using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p; -#endif +#include +#include #include #include #include From 6ea772196149a37c568f761a8851565622a1b9e3 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 27 Mar 2022 15:38:18 +0200 Subject: [PATCH 33/41] add TCM --- incl/iss/arch/riscv_hart_common.h | 45 ++++++++- incl/iss/arch/riscv_hart_m_p.h | 146 ++++++++++++++++++++++++++++-- incl/iss/arch/riscv_hart_mu_p.h | 124 ++++++++++++++----------- incl/iss/arch/tgc_mapper.h | 2 +- 4 files changed, 251 insertions(+), 66 deletions(-) diff --git a/incl/iss/arch/riscv_hart_common.h b/incl/iss/arch/riscv_hart_common.h index ffe87bc..8f79290 100644 --- a/incl/iss/arch/riscv_hart_common.h +++ b/incl/iss/arch/riscv_hart_common.h @@ -43,7 +43,7 @@ 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 features_e{FEAT_NONE, FEAT_PMP=1, FEAT_EXT_N=2, FEAT_CLIC=4, FEAT_DEBUG=8, FEAT_TCM=16}; enum riscv_csr { /* user-level CSR */ @@ -239,6 +239,49 @@ public: trap_store_page_fault(uint64_t badaddr) : trap_access(15 << 16, badaddr) {} }; + +inline void read_reg_uint32(uint64_t offs, uint32_t& reg, uint8_t *const data, unsigned length) { + auto reg_ptr = reinterpret_cast(®); + switch (offs & 0x3) { + case 0: + for (auto i = 0U; i < length; ++i) + *(data + i) = *(reg_ptr + i); + break; + case 1: + for (auto i = 0U; i < length; ++i) + *(data + i) = *(reg_ptr + 1 + i); + break; + case 2: + for (auto i = 0U; i < length; ++i) + *(data + i) = *(reg_ptr + 2 + i); + break; + case 3: + *data = *(reg_ptr + 3); + break; + } +} + +inline void write_reg_uint32(uint64_t offs, uint32_t& reg, const uint8_t *const data, unsigned length) { + auto reg_ptr = reinterpret_cast(®); + switch (offs & 0x3) { + case 0: + for (auto i = 0U; i < length; ++i) + *(reg_ptr + i) = *(data + i); + break; + case 1: + for (auto i = 0U; i < length; ++i) + *(reg_ptr + 1 + i) = *(data + i); + break; + case 2: + for (auto i = 0U; i < length; ++i) + *(reg_ptr + 2 + i) = *(data + i); + break; + case 3: + *(reg_ptr + 3) = *data ; + break; + } +} + } } diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index b55625c..4405b28 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -97,8 +97,10 @@ public: using reg_t = typename core::reg_t; using addr_t = typename core::addr_t; - using rd_csr_f = iss::status (this_class::*)(unsigned addr, reg_t &); - using wr_csr_f = iss::status (this_class::*)(unsigned addr, reg_t); + using rd_csr_f = iss::status (this_class::*)(unsigned addr, reg_t &); + using wr_csr_f = iss::status (this_class::*)(unsigned addr, reg_t); + using mem_read_f = iss::status(phys_addr_t addr, unsigned, uint8_t *const); + using mem_write_f = iss::status(phys_addr_t addr, unsigned, uint8_t const *const); // primary template template struct hart_state {}; @@ -294,6 +296,8 @@ protected: }; std::vector clic_int_reg; + std::vector tcm; + 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); @@ -337,6 +341,10 @@ protected: void check_interrupt(); bool pmp_check(const access_type type, const uint64_t addr, const unsigned len); + std::vector> memfn_range; + std::vector> memfn_read; + std::vector> memfn_write; + void insert_mem_range(uint64_t, uint64_t, std::function, std::function); uint64_t clic_base_addr{0}; unsigned clic_num_irq{0}; unsigned clic_num_trigger{0}; @@ -407,10 +415,52 @@ 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_CLIC) { + csr_rd_cb[mtvt] = &this_class::read_csr_reg; + csr_wr_cb[mtvt] = &this_class::write_csr_reg; + csr_rd_cb[mxnti] = &this_class::read_csr_reg; + csr_wr_cb[mxnti] = &this_class::write_csr_reg; + csr_rd_cb[mintstatus] = &this_class::read_csr_reg; + csr_wr_cb[mintstatus] = &this_class::write_null; + csr_rd_cb[mscratchcsw] = &this_class::read_csr_reg; + csr_wr_cb[mscratchcsw] = &this_class::write_csr_reg; + csr_rd_cb[mscratchcswl] = &this_class::read_csr_reg; + csr_wr_cb[mscratchcswl] = &this_class::write_csr_reg; + csr_rd_cb[mintthresh] = &this_class::read_csr_reg; + csr_wr_cb[mintthresh] = &this_class::write_intthresh; + csr_rd_cb[mclicbase] = &this_class::read_csr_reg; + csr_wr_cb[mclicbase] = &this_class::write_null; + + clic_base_addr=0xC0000000; + clic_num_irq=16; + clic_int_reg.resize(clic_num_irq); + clic_cfg_reg=0x20; + clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + clic_num_irq; + mcause_max_irq=clic_num_irq+16; + insert_mem_range(clic_base_addr, 0x5000UL, + [this](phys_addr_t addr, unsigned length, uint8_t * const data) { return read_clic(addr.val, length, data);}, + [this](phys_addr_t addr, unsigned length, uint8_t const * const data) {return write_clic(addr.val, length, data);}); + } + if(FEAT & FEAT_TCM) { + tcm.resize(0x8000); + std::function read_clic_cb = [this](phys_addr_t addr, unsigned length, uint8_t * const data) { + auto offset=addr.val-0x10000000; + std::copy(tcm.data() + offset, tcm.data() + offset + length, data); + return iss::Ok; + }; + std::function write_clic_cb = [this](phys_addr_t addr, unsigned length, uint8_t const * const data) { + auto offset=addr.val-0x10000000; + std::copy(data, data + length, tcm.data() + offset); + return iss::Ok; + }; + insert_mem_range(0x10000000, 0x8000UL, read_clic_cb, write_clic_cb); + } if(FEAT & FEAT_DEBUG){ csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg; @@ -489,6 +539,20 @@ template std::pair riscv_hart_m throw std::runtime_error("memory load file not found"); } +template +inline void riscv_hart_m_p::insert_mem_range(uint64_t base, uint64_t size, std::function rd_f, + std::function wr_fn) { + std::tuple entry{base, size}; + auto it = std::upper_bound( memfn_range.begin(), memfn_range.end(), entry, + [](std::tuple const& a, std::tuple const& b){ + return std::get<0>(a)(b); + }); + auto idx = std::distance(memfn_range.begin(), it); + memfn_range.insert(it, entry); + memfn_read.insert(std::begin(memfn_read)+idx, rd_f); + memfn_write.insert(std::begin(memfn_write)+idx, wr_fn); +} + 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) { @@ -517,9 +581,20 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce fault_data=addr; return iss::Err; } - auto res = type==iss::address_type::PHYSICAL? - read_mem( BASE::v2p(phys_addr_t{access, space, addr}), length, data): - read_mem( BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); + auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr}); + auto res = iss::Err; + if(access != access_type::FETCH && memfn_range.size()){ + auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){ + return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val; + }); + if(it!=std::end(memfn_range)) { + auto idx = std::distance(std::begin(memfn_range), it); + res = memfn_read[idx](phys_addr, length, data); + } else + res = read_mem( phys_addr, length, data); + } else { + res = read_mem( phys_addr, length, data); + } if (unlikely(res != iss::Ok)){ this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault fault_data=addr; @@ -594,14 +669,25 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc return iss::Err; } try { - if(!(access && iss::access_type::DEBUG) && length>1 && (addr&(length-1))){ + if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){ this->reg.trap_state = 1<<31 | 6<<16; fault_data=addr; return iss::Err; } - auto res = type==iss::address_type::PHYSICAL? - write_mem(phys_addr_t{access, space, addr}, length, data): - write_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); + auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr}); + auto res = iss::Err; + if(access != access_type::FETCH && memfn_range.size()){ + auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){ + return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val; + }); + if(it!=std::end(memfn_range)) { + auto idx = std::distance(std::begin(memfn_range), it); + res = memfn_write[idx]( phys_addr, length, data); + } else + res = write_mem( phys_addr, length, data); + } else { + res = write_mem( phys_addr, length, data); + } if (unlikely(res != iss::Ok)) { this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) fault_data=addr; @@ -874,6 +960,12 @@ template iss::status riscv_hart_m_p return iss::Ok; } +template +iss::status riscv_hart_m_p::write_intthresh(unsigned addr, reg_t val) { + csr[addr]= val &0xff; + 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); @@ -977,6 +1069,42 @@ iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned le return iss::Ok; } +template +iss::status riscv_hart_m_p::read_clic(uint64_t addr, unsigned length, uint8_t *const data) { + if(addr==clic_base_addr) { // cliccfg + *data=clic_cfg_reg; + for(auto i=1; i=(clic_base_addr+4) && (addr+length)<=(clic_base_addr+8)){ // clicinfo + read_reg_uint32(addr, clic_info_reg, data, length); + } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0x40+clic_num_trigger*4)){ // clicinttrig + auto offset = ((addr&0x7fff)-0x40)/4; + read_reg_uint32(addr, clic_inttrig_reg[offset], data, length); + } else if(addr>=(clic_base_addr+0x1000) && (addr+length)<=(clic_base_addr+clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl + auto offset = ((addr&0x7fff)-0x1000)/4; + read_reg_uint32(addr, clic_int_reg[offset].raw, data, length); + } else { + for(auto i = 0U; i +iss::status riscv_hart_m_p::write_clic(uint64_t addr, unsigned length, const uint8_t *const data) { + if(addr==clic_base_addr) { // cliccfg + clic_cfg_reg = *data; + clic_cfg_reg&= 0x7e; +// } else if(addr>=(clic_base_addr+4) && (addr+length)<=(clic_base_addr+4)){ // clicinfo +// write_uint32(addr, clic_info_reg, data, length); + } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0xC0)){ // clicinttrig + auto offset = ((addr&0x7fff)-0x40)/4; + write_reg_uint32(addr, clic_inttrig_reg[offset], data, length); + } else if(addr>=(clic_base_addr+0x1000) && (addr+length)<=(clic_base_addr+clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl + auto offset = ((addr&0x7fff)-0x1000)/4; + write_reg_uint32(addr, clic_int_reg[offset].raw, data, length); + } + return iss::Ok; +} + template inline void riscv_hart_m_p::reset(uint64_t address) { BASE::reset(address); state.mstatus = hart_state_type::mstatus_reset_val; diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index aafd204..722e221 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -97,8 +97,10 @@ public: using reg_t = typename core::reg_t; using addr_t = typename core::addr_t; - using rd_csr_f = iss::status (this_class::*)(unsigned addr, reg_t &); - using wr_csr_f = iss::status (this_class::*)(unsigned addr, reg_t); + using rd_csr_f = iss::status (this_class::*)(unsigned addr, reg_t &); + using wr_csr_f = iss::status (this_class::*)(unsigned addr, reg_t); + using mem_read_f = iss::status(phys_addr_t addr, unsigned, uint8_t *const); + using mem_write_f = iss::status(phys_addr_t addr, unsigned, uint8_t const *const); // primary template template struct hart_state {}; @@ -309,6 +311,8 @@ protected: }; std::vector clic_int_reg; + std::vector tcm; + 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); @@ -355,6 +359,10 @@ protected: void check_interrupt(); bool pmp_check(const access_type type, const uint64_t addr, const unsigned len); + std::vector> memfn_range; + std::vector> memfn_read; + std::vector> memfn_write; + void insert_mem_range(uint64_t, uint64_t, std::function, std::function); uint64_t clic_base_addr{0}; unsigned clic_num_irq{0}; unsigned clic_num_trigger{0}; @@ -483,6 +491,23 @@ riscv_hart_mu_p::riscv_hart_mu_p() clic_cfg_reg=0x20; clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + clic_num_irq; mcause_max_irq=clic_num_irq+16; + insert_mem_range(clic_base_addr, 0x5000UL, + [this](phys_addr_t addr, unsigned length, uint8_t * const data) { return read_clic(addr.val, length, data);}, + [this](phys_addr_t addr, unsigned length, uint8_t const * const data) {return write_clic(addr.val, length, data);}); + } + if(FEAT & FEAT_TCM) { + tcm.resize(0x8000); + std::function read_clic_cb = [this](phys_addr_t addr, unsigned length, uint8_t * const data) { + auto offset=addr.val-0x10000000; + std::copy(tcm.data() + offset, tcm.data() + offset + length, data); + return iss::Ok; + }; + std::function write_clic_cb = [this](phys_addr_t addr, unsigned length, uint8_t const * const data) { + auto offset=addr.val-0x10000000; + std::copy(data, data + length, tcm.data() + offset); + return iss::Ok; + }; + insert_mem_range(0x10000000, 0x8000UL, read_clic_cb, write_clic_cb); } if(FEAT & FEAT_DEBUG){ csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; @@ -562,6 +587,20 @@ template std::pair riscv_hart_m throw std::runtime_error("memory load file not found"); } +template +inline void riscv_hart_mu_p::insert_mem_range(uint64_t base, uint64_t size, std::function rd_f, + std::function wr_fn) { + std::tuple entry{base, size}; + auto it = std::upper_bound( memfn_range.begin(), memfn_range.end(), entry, + [](std::tuple const& a, std::tuple const& b){ + return std::get<0>(a)(b); + }); + auto idx = std::distance(memfn_range.begin(), it); + memfn_range.insert(it, entry); + memfn_read.insert(std::begin(memfn_read)+idx, rd_f); + memfn_write.insert(std::begin(memfn_write)+idx, wr_fn); +} + template inline iss::status riscv_hart_mu_p::write_pmpcfg_reg(unsigned addr, reg_t val) { csr[addr] = val & 0x9f9f9f9f; @@ -688,8 +727,15 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc } auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr}); auto res = iss::Err; - if((FEAT & FEAT_CLIC) && access != access_type::FETCH && phys_addr.val>=clic_base_addr && (phys_addr.val+length)<=(clic_base_addr+0x5000)){ //TODO: should be a constant - res = read_clic(phys_addr.val, length, data); + if(access != access_type::FETCH && memfn_range.size()){ + auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){ + return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val; + }); + if(it!=std::end(memfn_range)) { + auto idx = std::distance(std::begin(memfn_range), it); + res = memfn_read[idx](phys_addr, length, data); + } else + res = read_mem( phys_addr, length, data); } else { res = read_mem( phys_addr, length, data); } @@ -781,8 +827,19 @@ iss::status riscv_hart_mu_p::write(const address_type type, const ac return iss::Err; } auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr}); - auto res = ((FEAT & FEAT_CLIC) && phys_addr.val>=clic_base_addr && (phys_addr.val+length)<=(clic_base_addr+0x5000))? //TODO: should be a constant - write_clic(phys_addr.val, length, data) : write_mem( phys_addr, length, data); + auto res = iss::Err; + if(access != access_type::FETCH && memfn_range.size()){ + auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){ + return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val; + }); + if(it!=std::end(memfn_range)) { + auto idx = std::distance(std::begin(memfn_range), it); + res = memfn_write[idx]( phys_addr, length, data); + } else + res = write_mem( phys_addr, length, data); + } else { + res = write_mem( phys_addr, length, data); + } if (unlikely(res != iss::Ok)) { this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) fault_data=addr; @@ -1111,8 +1168,7 @@ iss::status riscv_hart_mu_p::write_mem(phys_addr_t paddr, unsigned l case 0x10023000: // UART1 base, TXFIFO reg uart_buf << (char)data[0]; if (((char)data[0]) == '\n' || data[0] == 0) { - // LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send - // '"<>16)&0x3)<<" send '"<::write_mem(phys_addr_t paddr, unsigned l return iss::Ok; } -void read_uint32(uint64_t offs, uint32_t& reg, uint8_t *const data, unsigned length) { - auto reg_ptr = reinterpret_cast(®); - switch (offs & 0x3) { - case 0: - for (auto i = 0U; i < length; ++i) - *(data + i) = *(reg_ptr + i); - break; - case 1: - for (auto i = 0U; i < length; ++i) - *(data + i) = *(reg_ptr + 1 + i); - break; - case 2: - for (auto i = 0U; i < length; ++i) - *(data + i) = *(reg_ptr + 2 + i); - break; - case 3: - *data = *(reg_ptr + 3); - break; - } -} - -void write_uint32(uint64_t offs, uint32_t& reg, const uint8_t *const data, unsigned length) { - auto reg_ptr = reinterpret_cast(®); - switch (offs & 0x3) { - case 0: - for (auto i = 0U; i < length; ++i) - *(reg_ptr + i) = *(data + i); - break; - case 1: - for (auto i = 0U; i < length; ++i) - *(reg_ptr + 1 + i) = *(data + i); - break; - case 2: - for (auto i = 0U; i < length; ++i) - *(reg_ptr + 2 + i) = *(data + i); - break; - case 3: - *(reg_ptr + 3) = *data ; - break; - } -} - template iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned length, uint8_t *const data) { if(addr==clic_base_addr) { // cliccfg *data=clic_cfg_reg; for(auto i=1; i=(clic_base_addr+4) && (addr+length)<=(clic_base_addr+8)){ // clicinfo - read_uint32(addr, clic_info_reg, data, length); + read_reg_uint32(addr, clic_info_reg, data, length); } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0x40+clic_num_trigger*4)){ // clicinttrig auto offset = ((addr&0x7fff)-0x40)/4; - read_uint32(addr, clic_inttrig_reg[offset], data, length); + read_reg_uint32(addr, clic_inttrig_reg[offset], data, length); } else if(addr>=(clic_base_addr+0x1000) && (addr+length)<=(clic_base_addr+clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl auto offset = ((addr&0x7fff)-0x1000)/4; - read_uint32(addr, clic_int_reg[offset].raw, data, length); + read_reg_uint32(addr, clic_int_reg[offset].raw, data, length); } else { for(auto i = 0U; i::write_clic(uint64_t addr, unsigned leng // write_uint32(addr, clic_info_reg, data, length); } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0xC0)){ // clicinttrig auto offset = ((addr&0x7fff)-0x40)/4; - write_uint32(addr, clic_inttrig_reg[offset], data, length); + write_reg_uint32(addr, clic_inttrig_reg[offset], data, length); } else if(addr>=(clic_base_addr+0x1000) && (addr+length)<=(clic_base_addr+clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl auto offset = ((addr&0x7fff)-0x1000)/4; - write_uint32(addr, clic_int_reg[offset].raw, data, length); + write_reg_uint32(addr, clic_int_reg[offset].raw, data, length); } return iss::Ok; } diff --git a/incl/iss/arch/tgc_mapper.h b/incl/iss/arch/tgc_mapper.h index 1d4dd73..7173d7b 100644 --- a/incl/iss/arch/tgc_mapper.h +++ b/incl/iss/arch/tgc_mapper.h @@ -37,7 +37,7 @@ using tgc_e_plat_type = iss::arch::riscv_hart_mu_p; +using tgc_x_plat_type = iss::arch::riscv_hart_mu_p; #endif #endif From 0aea1d0177ad4514923a712cb69bfcbe34eb15a9 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 27 Mar 2022 17:21:46 +0200 Subject: [PATCH 34/41] remove mcounteren in M-mode only wrapper --- incl/iss/arch/riscv_hart_m_p.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index 4405b28..d54fd57 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -415,8 +415,6 @@ 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; From 49be14358815794b91bc7bd8d6b7aca26d1002b9 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 27 Mar 2022 17:54:08 +0200 Subject: [PATCH 35/41] make features configurable --- incl/iss/arch/riscv_hart_common.h | 8 ++++++ incl/iss/arch/riscv_hart_mu_p.h | 47 +++++++++++++++---------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/incl/iss/arch/riscv_hart_common.h b/incl/iss/arch/riscv_hart_common.h index 8f79290..f8584be 100644 --- a/incl/iss/arch/riscv_hart_common.h +++ b/incl/iss/arch/riscv_hart_common.h @@ -214,6 +214,14 @@ struct vm_info { bool is_active() { return levels; } }; +struct feature_config { + uint64_t clic_base{0xc0000000}; + unsigned clic_num_irq{16}; + unsigned clic_num_trigger{0}; + uint64_t tcm_base{0x10000000}; + uint64_t tcm_size{0x8000}; +}; + class trap_load_access_fault : public trap_access { public: trap_load_access_fault(uint64_t badaddr) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 722e221..ae5031f 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -197,7 +197,7 @@ public: return traits::MISA_VAL&0b0100?~1:~3; } - riscv_hart_mu_p(); + riscv_hart_mu_p(feature_config cfg = feature_config{}); virtual ~riscv_hart_mu_p() = default; void reset(uint64_t address) override; @@ -363,23 +363,22 @@ protected: std::vector> memfn_read; std::vector> memfn_write; void insert_mem_range(uint64_t, uint64_t, std::function, std::function); - uint64_t clic_base_addr{0}; - unsigned clic_num_irq{0}; - unsigned clic_num_trigger{0}; + feature_config cfg; unsigned mcause_max_irq{16}; inline bool debug_mode_active() {return this->reg.PRIV&0x4;} }; template -riscv_hart_mu_p::riscv_hart_mu_p() +riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg) : state() -, instr_if(*this) { +, instr_if(*this) +, cfg(cfg) { // reset values csr[misa] = traits::MISA_VAL; csr[mvendorid] = 0x669; csr[marchid] = traits::MARCHID_VAL; csr[mimpid] = 1; - csr[mclicbase] = 0xc0000000; // TODO: should be taken from YAML file + csr[mclicbase] = cfg.clic_base; // TODO: should be taken from YAML file uart_buf.str(""); for (unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr){ @@ -485,29 +484,27 @@ riscv_hart_mu_p::riscv_hart_mu_p() csr_rd_cb[mclicbase] = &this_class::read_csr_reg; csr_wr_cb[mclicbase] = &this_class::write_null; - clic_base_addr=0xC0000000; - clic_num_irq=16; - clic_int_reg.resize(clic_num_irq); + clic_int_reg.resize(cfg.clic_num_irq); clic_cfg_reg=0x20; - clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + clic_num_irq; - mcause_max_irq=clic_num_irq+16; - insert_mem_range(clic_base_addr, 0x5000UL, + clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq; + mcause_max_irq=cfg.clic_num_irq+16; + insert_mem_range(cfg.clic_base, 0x5000UL, [this](phys_addr_t addr, unsigned length, uint8_t * const data) { return read_clic(addr.val, length, data);}, [this](phys_addr_t addr, unsigned length, uint8_t const * const data) {return write_clic(addr.val, length, data);}); } if(FEAT & FEAT_TCM) { - tcm.resize(0x8000); + tcm.resize(cfg.tcm_size); std::function read_clic_cb = [this](phys_addr_t addr, unsigned length, uint8_t * const data) { - auto offset=addr.val-0x10000000; + auto offset=addr.val-this->cfg.tcm_base; std::copy(tcm.data() + offset, tcm.data() + offset + length, data); return iss::Ok; }; std::function write_clic_cb = [this](phys_addr_t addr, unsigned length, uint8_t const * const data) { - auto offset=addr.val-0x10000000; + auto offset=addr.val-this->cfg.tcm_base; std::copy(data, data + length, tcm.data() + offset); return iss::Ok; }; - insert_mem_range(0x10000000, 0x8000UL, read_clic_cb, write_clic_cb); + insert_mem_range(cfg.tcm_base, cfg.tcm_size, read_clic_cb, write_clic_cb); } if(FEAT & FEAT_DEBUG){ csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg; @@ -1239,15 +1236,15 @@ iss::status riscv_hart_mu_p::write_mem(phys_addr_t paddr, unsigned l template iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned length, uint8_t *const data) { - if(addr==clic_base_addr) { // cliccfg + if(addr==cfg.clic_base) { // cliccfg *data=clic_cfg_reg; for(auto i=1; i=(clic_base_addr+4) && (addr+length)<=(clic_base_addr+8)){ // clicinfo + } else if(addr>=(cfg.clic_base+4) && (addr+length)<=(cfg.clic_base+8)){ // clicinfo read_reg_uint32(addr, clic_info_reg, data, length); - } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0x40+clic_num_trigger*4)){ // clicinttrig + } else if(addr>=(cfg.clic_base+0x40) && (addr+length)<=(cfg.clic_base+0x40+cfg.clic_num_trigger*4)){ // clicinttrig auto offset = ((addr&0x7fff)-0x40)/4; read_reg_uint32(addr, clic_inttrig_reg[offset], data, length); - } else if(addr>=(clic_base_addr+0x1000) && (addr+length)<=(clic_base_addr+clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl + } else if(addr>=(cfg.clic_base+0x1000) && (addr+length)<=(cfg.clic_base+cfg.clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl auto offset = ((addr&0x7fff)-0x1000)/4; read_reg_uint32(addr, clic_int_reg[offset].raw, data, length); } else { @@ -1258,15 +1255,15 @@ iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned lengt template iss::status riscv_hart_mu_p::write_clic(uint64_t addr, unsigned length, const uint8_t *const data) { - if(addr==clic_base_addr) { // cliccfg + if(addr==cfg.clic_base) { // cliccfg clic_cfg_reg = *data; clic_cfg_reg&= 0x7e; -// } else if(addr>=(clic_base_addr+4) && (addr+length)<=(clic_base_addr+4)){ // clicinfo +// } else if(addr>=(cfg.clic_base+4) && (addr+length)<=(cfg.clic_base+4)){ // clicinfo // write_uint32(addr, clic_info_reg, data, length); - } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0xC0)){ // clicinttrig + } else if(addr>=(cfg.clic_base+0x40) && (addr+length)<=(cfg.clic_base+0xC0)){ // clicinttrig auto offset = ((addr&0x7fff)-0x40)/4; write_reg_uint32(addr, clic_inttrig_reg[offset], data, length); - } else if(addr>=(clic_base_addr+0x1000) && (addr+length)<=(clic_base_addr+clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl + } else if(addr>=(cfg.clic_base+0x1000) && (addr+length)<=(cfg.clic_base+cfg.clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl auto offset = ((addr&0x7fff)-0x1000)/4; write_reg_uint32(addr, clic_int_reg[offset].raw, data, length); } From 58311b37dbec793328f4d03f3ec5742cafc99ef3 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Mon, 28 Mar 2022 11:16:09 +0200 Subject: [PATCH 36/41] Merge branch 'feature/reduced_output' of https://git.minres.com/DBT-RISE/DBT-RISE-TGC.git into feature/reduced_output --- src/plugin/pctrace.cpp | 70 +++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/plugin/pctrace.cpp b/src/plugin/pctrace.cpp index 97ca4fc..e178072 100644 --- a/src/plugin/pctrace.cpp +++ b/src/plugin/pctrace.cpp @@ -89,45 +89,45 @@ inline string formatPC(uint64_t pc) { } void iss::plugin::cov::callback(instr_info_t iinfo, const exec_info& einfo) { - auto delay = 0; - auto entry = delays[iinfo.instr_id]; - bool taken = einfo.branch_taken; - if (einfo.branch_taken) - delay = entry.taken; - else - delay = entry.not_taken; - - if (first){ - output << formatPC(instr_if->get_pc()) << "," << delay; - first = false; - } - if(instr_if->get_next_pc()-instr_if->get_pc() != delays[iinfo.instr_id].size/8){ - //The goal is to keep the output in start-target pairs, so after a jump the target address needs to get written - //to the output. If the target happens to also be a start, we keep the pairing by adding a 0-delay entry. - if (jumped) - output <<"\n" <get_pc()) << "," << 0; - output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; - jumped = true; - } - else{ - if (jumped){ - output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; - jumped = false; - } - else if(delay!=1){ - output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; - output <<"\n" << formatPC(instr_if->get_pc()) << "," << 0; - } - - } - -//source code for the full output // auto delay = 0; // auto entry = delays[iinfo.instr_id]; // bool taken = einfo.branch_taken; // if (einfo.branch_taken) // delay = entry.taken; // else -// delay = entry.not_taken; -// output<get_pc() <<"," << delay << "\n"; +// delay = entry.not_taken; +// +// if (first){ +// output << formatPC(instr_if->get_pc()) << "," << delay; +// first = false; +// } +// if(instr_if->get_next_pc()-instr_if->get_pc() != delays[iinfo.instr_id].size/8){ +// //The goal is to keep the output in start-target pairs, so after a jump the target address needs to get written +// //to the output. If the target happens to also be a start, we keep the pairing by adding a 0-delay entry. +// if (jumped) +// output <<"\n" <get_pc()) << "," << 0; +// output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; +// jumped = true; +// } +// else{ +// if (jumped){ +// output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; +// jumped = false; +// } +// else if(delay!=1){ +// output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; +// output <<"\n" << formatPC(instr_if->get_pc()) << "," << 0; +// } +// +// } + +//source code for the full output + auto delay = 0; + auto entry = delays[iinfo.instr_id]; + bool taken = einfo.branch_taken; + if (einfo.branch_taken) + delay = entry.taken; + else + delay = entry.not_taken; + output<get_pc() <<"," << delay << "\n"; } From 00d2d06cbde18e69f5ed561d973848275762277e Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 31 Mar 2022 20:33:12 +0200 Subject: [PATCH 37/41] adapt to privileged spec --- incl/iss/arch/riscv_hart_m_p.h | 11 +---------- incl/iss/arch/riscv_hart_msu_vp.h | 16 +++------------- incl/iss/arch/riscv_hart_mu_p.h | 19 +++++-------------- 3 files changed, 9 insertions(+), 37 deletions(-) diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index d54fd57..f67ad05 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -314,7 +314,6 @@ protected: iss::status read_ie(unsigned addr, reg_t &val); iss::status write_ie(unsigned addr, reg_t val); 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_epc(unsigned addr, reg_t val); iss::status write_intstatus(unsigned addr, reg_t val); @@ -411,7 +410,7 @@ riscv_hart_m_p::riscv_hart_m_p() csr_rd_cb[mtvec] = &this_class::read_tvec; csr_wr_cb[mepc] = &this_class::write_epc; csr_rd_cb[mip] = &this_class::read_ip; - csr_wr_cb[mip] = &this_class::write_ip; + csr_wr_cb[mip] = &this_class::write_null; csr_rd_cb[mie] = &this_class::read_ie; csr_wr_cb[mie] = &this_class::write_ie; csr_rd_cb[mhartid] = &this_class::read_hartid; @@ -906,14 +905,6 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::write_ip(unsigned addr, reg_t val) { - auto mask = get_irq_mask(); - mask &= 0xf; // only xSIP is writable - csr[mip] = (csr[mip] & ~mask) | (val & mask); - check_interrupt(); - return iss::Ok; -} - template iss::status riscv_hart_m_p::write_epc(unsigned addr, reg_t val) { csr[addr] = val & get_pc_mask(); return iss::Ok; diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h index 853a4bf..607c952 100644 --- a/incl/iss/arch/riscv_hart_msu_vp.h +++ b/incl/iss/arch/riscv_hart_msu_vp.h @@ -400,7 +400,6 @@ private: iss::status read_ie(unsigned addr, reg_t &val); iss::status write_ie(unsigned addr, reg_t val); 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_epc(unsigned addr, reg_t val); iss::status read_satp(unsigned addr, reg_t &val); @@ -499,11 +498,11 @@ riscv_hart_msu_vp::riscv_hart_msu_vp() csr_wr_cb[sepc] = &this_class::write_epc; csr_wr_cb[uepc] = &this_class::write_epc; csr_rd_cb[mip] = &this_class::read_ip; - csr_wr_cb[mip] = &this_class::write_ip; + csr_wr_cb[mip] = &this_class::write_null; csr_rd_cb[sip] = &this_class::read_ip; - csr_wr_cb[sip] = &this_class::write_ip; + csr_wr_cb[sip] = &this_class::write_null; csr_rd_cb[uip] = &this_class::read_ip; - csr_wr_cb[uip] = &this_class::write_ip; + csr_wr_cb[uip] = &this_class::write_null; csr_rd_cb[mie] = &this_class::read_ie; csr_wr_cb[mie] = &this_class::write_ie; csr_rd_cb[sie] = &this_class::read_ie; @@ -959,15 +958,6 @@ template iss::status riscv_hart_msu_vp::read_ip(unsigned a return iss::Ok; } -template iss::status riscv_hart_msu_vp::write_ip(unsigned addr, reg_t val) { - auto req_priv_lvl = (addr >> 8) & 0x3; - auto mask = get_irq_mask(req_priv_lvl); - mask &= ~(1 << 7); // MTIP is read only - csr[mip] = (csr[mip] & ~mask) | (val & mask); - check_interrupt(); - return iss::Ok; -} - 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 ae5031f..32f951d 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -329,7 +329,6 @@ protected: iss::status read_ie(unsigned addr, reg_t &val); iss::status write_ie(unsigned addr, reg_t val); iss::status read_ip(unsigned addr, reg_t &val); - iss::status write_ip(unsigned addr, reg_t val); iss::status write_ideleg(unsigned addr, reg_t val); iss::status write_edeleg(unsigned addr, reg_t val); iss::status read_hartid(unsigned addr, reg_t &val); @@ -432,7 +431,7 @@ riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg) csr_rd_cb[mtvec] = &this_class::read_tvec; csr_wr_cb[mepc] = &this_class::write_epc; csr_rd_cb[mip] = &this_class::read_ip; - csr_wr_cb[mip] = &this_class::write_ip; + csr_wr_cb[mip] = &this_class::write_null; csr_rd_cb[mie] = &this_class::read_ie; csr_wr_cb[mie] = &this_class::write_ie; csr_rd_cb[mhartid] = &this_class::read_hartid; @@ -461,7 +460,7 @@ riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg) csr_rd_cb[uie] = &this_class::read_ie; csr_wr_cb[uie] = &this_class::write_ie; csr_rd_cb[uip] = &this_class::read_ip; - csr_wr_cb[uip] = &this_class::write_ip; + csr_wr_cb[uip] = &this_class::write_null; csr_wr_cb[uepc] = &this_class::write_epc; csr_rd_cb[ustatus] = &this_class::read_status; csr_wr_cb[ustatus] = &this_class::write_status; @@ -1062,14 +1061,6 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_ip(unsigned addr, reg_t val) { - 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; -} - template iss::status riscv_hart_mu_p::write_ideleg(unsigned addr, reg_t val) { auto mask = 0b000100010001; // only U mode supported csr[mideleg] = (csr[mideleg] & ~mask) | (val & mask); @@ -1244,7 +1235,7 @@ iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned lengt } else if(addr>=(cfg.clic_base+0x40) && (addr+length)<=(cfg.clic_base+0x40+cfg.clic_num_trigger*4)){ // clicinttrig auto offset = ((addr&0x7fff)-0x40)/4; read_reg_uint32(addr, clic_inttrig_reg[offset], data, length); - } else if(addr>=(cfg.clic_base+0x1000) && (addr+length)<=(cfg.clic_base+cfg.clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl + } else if(addr>=(cfg.clic_base+0x1000) && (addr+length)<=(cfg.clic_base+0x1000+cfg.clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl auto offset = ((addr&0x7fff)-0x1000)/4; read_reg_uint32(addr, clic_int_reg[offset].raw, data, length); } else { @@ -1260,10 +1251,10 @@ iss::status riscv_hart_mu_p::write_clic(uint64_t addr, unsigned leng clic_cfg_reg&= 0x7e; // } else if(addr>=(cfg.clic_base+4) && (addr+length)<=(cfg.clic_base+4)){ // clicinfo // write_uint32(addr, clic_info_reg, data, length); - } else if(addr>=(cfg.clic_base+0x40) && (addr+length)<=(cfg.clic_base+0xC0)){ // clicinttrig + } else if(addr>=(cfg.clic_base+0x40) && (addr+length)<=(cfg.clic_base+0x40+cfg.clic_num_trigger*4)){ // clicinttrig auto offset = ((addr&0x7fff)-0x40)/4; write_reg_uint32(addr, clic_inttrig_reg[offset], data, length); - } else if(addr>=(cfg.clic_base+0x1000) && (addr+length)<=(cfg.clic_base+cfg.clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl + } else if(addr>=(cfg.clic_base+0x1000) && (addr+length)<=(cfg.clic_base+0x1000+cfg.clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl auto offset = ((addr&0x7fff)-0x1000)/4; write_reg_uint32(addr, clic_int_reg[offset].raw, data, length); } From 9465cffe79f46290032d39ba305cb8ce128563ba Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 9 Apr 2022 14:55:36 +0200 Subject: [PATCH 38/41] adapt to change in dbt-rise-core --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 64f83ff..28ba1da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,9 +72,9 @@ endif() target_include_directories(${PROJECT_NAME} PUBLIC incl) target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp Boost::coroutine) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive) + target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-rise-core -Wl,--no-whole-archive) else() - target_link_libraries(${PROJECT_NAME} PUBLIC dbt-core) + target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-core) endif() if(TARGET CONAN_PKG::elfio) target_link_libraries(${PROJECT_NAME} PUBLIC CONAN_PKG::elfio) From 15cd26f80023dff61e92574d27e3f0bdea363cc2 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 10 Apr 2022 12:15:40 +0200 Subject: [PATCH 39/41] remove CoreDSL ISA repo --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 43cd095..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "gen_input/CoreDSL-Instruction-Set-Description"] - path = gen_input/CoreDSL-Instruction-Set-Description - url = ../CoreDSL-Instruction-Set-Description.git From c054d75717dcefbc2048ab277fdfe1cb428640ef Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 10 Apr 2022 18:55:44 +0200 Subject: [PATCH 40/41] update to latest coredsl description --- incl/iss/arch/tgc_c.h | 2 +- src/vm/interp/vm_tgc_c.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/incl/iss/arch/tgc_c.h b/incl/iss/arch/tgc_c.h index 74ab760..619034d 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", "DPC"}}; - enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, RFS=32, XLEN=32, CSR_SIZE=4096, INSTR_ALIGNMENT=2, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; + enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, RFS=32, INSTR_ALIGNMENT=2, XLEN=32, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; 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 52fd588..ea76eaf 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -2001,7 +2001,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t rs1_idx = rs1 + 8; + uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = *(X+rs1_idx) >> shamt; } } catch(...){} @@ -2024,11 +2024,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { if(shamt) { - uint32_t rs1_idx = rs1 + 8; + uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt; } else if(traits::XLEN == 128) { - uint32_t rs1_idx = rs1 + 8; + uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64; } } catch(...){} @@ -2051,7 +2051,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t rs1_idx = rs1 + 8; + uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm); } } catch(...){} @@ -2074,7 +2074,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t rd_idx = rd + 8; + uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8); } } catch(...){} @@ -2097,7 +2097,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t rd_idx = rd + 8; + uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8); } } catch(...){} @@ -2120,7 +2120,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t rd_idx = rd + 8; + uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8); } } catch(...){} @@ -2143,7 +2143,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction try { { - uint32_t rd_idx = rd + 8; + uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8); } } catch(...){} From 477c530847656d6f6eaa0b743cfb99ce7ea4616d Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 13 Apr 2022 11:41:01 +0200 Subject: [PATCH 41/41] extend debug mode handling --- incl/iss/arch/riscv_hart_common.h | 2 +- incl/iss/arch/riscv_hart_m_p.h | 14 +++++++++----- incl/iss/arch/riscv_hart_mu_p.h | 13 ++++++++----- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/incl/iss/arch/riscv_hart_common.h b/incl/iss/arch/riscv_hart_common.h index f8584be..345fbeb 100644 --- a/incl/iss/arch/riscv_hart_common.h +++ b/incl/iss/arch/riscv_hart_common.h @@ -188,7 +188,7 @@ enum { template inline bool PTE_TABLE(T PTE) { return (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V); } -enum { PRIV_U = 0, PRIV_S = 1, PRIV_M = 3 }; +enum { PRIV_U = 0, PRIV_S = 1, PRIV_M = 3, PRIV_D = 4}; enum { ISA_A = 1, diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index f67ad05..bff635d 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -1127,6 +1127,7 @@ template uint64_t riscv_hart_m_p::e auto trap_id = bit_sub<0, 16>(flags); auto cause = bit_sub<16, 15>(flags); // calculate effective privilege level + unsigned new_priv = PRIV_M; if (trap_id == 0) { // exception if (cause == 11) cause = 0x8 + PRIV_M; // adjust environment call cause // store ret addr in xepc register @@ -1146,10 +1147,13 @@ template uint64_t riscv_hart_m_p::e 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; + if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) { + this->reg.DPC = addr; + csr[dcsr] = (csr[dcsr] & ~0x1c3) | (1<<6) | PRIV_M; //FIXME: cause should not be 4 (stepi) + new_priv = this->reg.PRIV | PRIV_D; + } else { + csr[mtval] = addr; + } break; case 4: case 6: @@ -1182,7 +1186,7 @@ template uint64_t riscv_hart_m_p::e this->reg.NEXT_PC = ivec & ~0x3UL; if ((ivec & 0x1) == 1 && trap_id != 0) this->reg.NEXT_PC += 4 * cause; // reset trap state - this->reg.PRIV = PRIV_M; + this->reg.PRIV = new_priv; this->reg.trap_state = 0; std::array buffer; #if defined(_MSC_VER) diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h index 32f951d..bd50342 100644 --- a/incl/iss/arch/riscv_hart_mu_p.h +++ b/incl/iss/arch/riscv_hart_mu_p.h @@ -1296,7 +1296,7 @@ template uint64_t riscv_hart_mu_p:: auto cause = bit_sub<16, 15>(flags); if (trap_id == 0 && cause == 11) cause = 0x8 + this->reg.PRIV; // adjust environment call cause // calculate effective privilege level - auto new_priv = PRIV_M; + unsigned new_priv = PRIV_M; if (trap_id == 0) { // exception if (this->reg.PRIV != PRIV_M && ((csr[medeleg] >> cause) & 0x1) != 0) new_priv = PRIV_U; @@ -1317,10 +1317,13 @@ template uint64_t riscv_hart_mu_p:: 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)] = addr; + if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) { + this->reg.DPC = addr; + csr[dcsr] = (csr[dcsr] & ~0x1c3) | (1<<6) | PRIV_M; //FIXME: cause should not be 4 (stepi) + new_priv = this->reg.PRIV | PRIV_D; + } else { + csr[utval | (new_priv << 8)] = addr; + } break; case 4: case 6: