diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description index 3cfac1d..89763fc 160000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ b/gen_input/CoreDSL-Instruction-Set-Description @@ -1 +1 @@ -Subproject commit 3cfac1d86f6532140a04cdfc1501f1b8f3729632 +Subproject commit 89763fcb973838a634e48ee05dca28782807b344 diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 57db9ca..010bcb7 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -33,7 +33,7 @@ def getRegisterSizes(){ def regs = registers.collect{it.size} regs[-1]=64 // correct for NEXT_PC - regs+=[32, 32, 32, 32, 64] // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT + regs+=[32, 32, 64] // append TRAP_STATE, PENDING_TRAP, ICOUNT return regs } %> diff --git a/gen_input/templates/interp/CORENAME.h.gtl b/gen_input/templates/interp/CORENAME.h.gtl index 69699b9..610fd14 100644 --- a/gen_input/templates/interp/CORENAME.h.gtl +++ b/gen_input/templates/interp/CORENAME.h.gtl @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2017 - 2020 MINRES Technologies GmbH + * Copyright (C) 2017 - 2021 MINRES Technologies GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,22 +29,23 @@ * POSSIBILITY OF SUCH DAMAGE. * *******************************************************************************/ -<% +<% +def nativeTypeSize(int size){ + if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64; +} def getRegisterSizes(){ - def regs = registers.collect{it.size} - regs[-1]=pc.size // correct for NEXT_PC - regs+=[32, 32, 32, 32, 64] // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT + def regs = registers.collect{nativeTypeSize(it.size)} + regs+=[32,32, 64] // append TRAP_STATE, PENDING_TRAP, ICOUNT return regs } def getRegisterOffsets(){ - def regs = registers.collect{it.offset} - def offs= regs[-1] - // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT offsets starting with NEXT_PC size - [pc.size/8, 4, 4, 4, 4].each{ sz -> - regs+=offs+sz - offs+=sz + def offset = 0 + def offsets = [] + getRegisterSizes().each { size -> + offsets< struct traits<${coreDef.name.toLowerCase()}> { constexpr static unsigned FP_REGS_SIZE = ${constants.find {it.name=='FLEN'}?.value?:0}; - enum reg_e {<% - registers.each { reg -> %> - ${reg.name},<% - }%> - NEXT_${pc.name}=NUM_REGS, - TRAP_STATE, + enum reg_e { + ${registers.collect{it.name}.join(', ')}, NUM_REGS, + TRAP_STATE=NUM_REGS, PENDING_TRAP, - MACHINE_STATE, - LAST_BRANCH, ICOUNT }; @@ -168,7 +164,6 @@ protected: registers.each { reg -> if(reg.size>0) {%> uint${byteSize(reg.size)}_t ${reg.name} = 0;<% }}%> - uint${byteSize(pc.size)}_t NEXT_${pc.name} = 0; uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; uint64_t icount = 0; } reg; diff --git a/gen_input/templates/interp/vm_CORENAME.cpp.gtl b/gen_input/templates/interp/vm_CORENAME.cpp.gtl index 6a3bbe6..1e7701e 100644 --- a/gen_input/templates/interp/vm_CORENAME.cpp.gtl +++ b/gen_input/templates/interp/vm_CORENAME.cpp.gtl @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2020 MINRES Technologies GmbH + * Copyright (C) 2021 MINRES Technologies GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -149,13 +149,14 @@ protected: this->core.leave_trap(lvl); auto pc_val = super::template read_mem(traits::CSR, (lvl << 8) + 0x41); this->template get_reg(traits::NEXT_PC) = pc_val; - this->template get_reg(traits::LAST_BRANCH) = std::numeric_limits::max(); } void wait(unsigned type){ this->core.wait_until(type); } + 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){return super::template read_mem(space, addr);} inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} @@ -196,17 +197,15 @@ private: // prepare execution uint${addrDataWidth}_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); uint${addrDataWidth}_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + uint${addrDataWidth}_t* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); + *NEXT_PC = *PC + ${instr.length/8}; // execute instruction <%instr.behavior.eachLine{%>${it} - <%}%>// post execution stuff<% if(instr.modifiesPC) { %> - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC);<% } else { %> - super::template get_reg(arch::traits::NEXT_PC) = pc.val + ${instr.length/8};<% } %> + <%}%>// post execution stuff if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx}); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h index d0ae20c..e834dd6 100644 --- a/incl/iss/arch/riscv_hart_m_p.h +++ b/incl/iss/arch/riscv_hart_m_p.h @@ -302,7 +302,7 @@ public: void write_mstatus(T val) { auto mask = get_mask(); - auto new_val = (mstatus.st.value & ~mask) | (val & mask); + auto new_val = (mstatus.storage.val & ~mask) | (val & mask); mstatus = new_val; } diff --git a/incl/iss/arch/tgf_b.h b/incl/iss/arch/tgf_b.h index d47e9cb..84a43bf 100644 --- a/incl/iss/arch/tgf_b.h +++ b/incl/iss/arch/tgf_b.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2017 - 2020 MINRES Technologies GmbH + * Copyright (C) 2017 - 2021 MINRES Technologies GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,56 +48,19 @@ template <> struct traits { constexpr static char const* const core_type = "TGF_B"; static constexpr std::array reg_names{ - {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "PRIV", "NUM_REGS"}}; + {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}}; static constexpr std::array reg_aliases{ - {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "PRIV", "NUM_REGS"}}; + {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}}; enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000000000000000100000000, PGSIZE=0x1000, PGMASK=0xfff, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3}; constexpr static unsigned FP_REGS_SIZE = 0; enum reg_e { - X0, - X1, - X2, - X3, - X4, - X5, - X6, - X7, - X8, - X9, - X10, - X11, - X12, - X13, - X14, - X15, - X16, - X17, - X18, - X19, - X20, - X21, - X22, - X23, - X24, - X25, - X26, - X27, - X28, - X29, - X30, - X31, - PC, - PRIV, - NUM_REGS, - NEXT_PC=NUM_REGS, - TRAP_STATE, + X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, PC, NEXT_PC, PRIV, NUM_REGS, + TRAP_STATE=NUM_REGS, PENDING_TRAP, - MACHINE_STATE, - LAST_BRANCH, ICOUNT }; @@ -111,11 +74,11 @@ template <> struct traits { using phys_addr_t = iss::typed_addr_t; - static constexpr std::array reg_bit_widths{ - {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,2,32,32,32,32,32,64}}; + static constexpr std::array reg_bit_widths{ + {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,8,32,32,64}}; - static constexpr std::array reg_byte_offsets{ - {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,133,137,141,145,149,153}}; + static constexpr std::array reg_byte_offsets{ + {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,137,141,145}}; static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); @@ -257,8 +220,8 @@ protected: uint32_t X30 = 0; uint32_t X31 = 0; uint32_t PC = 0; + uint32_t NEXT_PC = 0; uint8_t PRIV = 0; - uint32_t NEXT_PC = 0; uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; uint64_t icount = 0; } reg; diff --git a/incl/iss/arch/tgf_c.h b/incl/iss/arch/tgf_c.h index cee60b2..5aacf2f 100644 --- a/incl/iss/arch/tgf_c.h +++ b/incl/iss/arch/tgf_c.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2017 - 2020 MINRES Technologies GmbH + * Copyright (C) 2017 - 2021 MINRES Technologies GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,56 +48,19 @@ template <> struct traits { constexpr static char const* const core_type = "TGF_C"; static constexpr std::array reg_names{ - {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "PRIV", "NUM_REGS"}}; + {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}}; static constexpr std::array reg_aliases{ - {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "PRIV", "NUM_REGS"}}; + {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}}; enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; constexpr static unsigned FP_REGS_SIZE = 0; enum reg_e { - X0, - X1, - X2, - X3, - X4, - X5, - X6, - X7, - X8, - X9, - X10, - X11, - X12, - X13, - X14, - X15, - X16, - X17, - X18, - X19, - X20, - X21, - X22, - X23, - X24, - X25, - X26, - X27, - X28, - X29, - X30, - X31, - PC, - PRIV, - NUM_REGS, - NEXT_PC=NUM_REGS, - TRAP_STATE, + X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, PC, NEXT_PC, PRIV, NUM_REGS, + TRAP_STATE=NUM_REGS, PENDING_TRAP, - MACHINE_STATE, - LAST_BRANCH, ICOUNT }; @@ -111,11 +74,11 @@ template <> struct traits { using phys_addr_t = iss::typed_addr_t; - static constexpr std::array reg_bit_widths{ - {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,2,32,32,32,32,32,64}}; + static constexpr std::array reg_bit_widths{ + {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,8,32,32,64}}; - static constexpr std::array reg_byte_offsets{ - {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,133,137,141,145,149,153}}; + static constexpr std::array reg_byte_offsets{ + {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,137,141,145}}; static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); @@ -293,8 +256,8 @@ protected: uint32_t X30 = 0; uint32_t X31 = 0; uint32_t PC = 0; + uint32_t NEXT_PC = 0; uint8_t PRIV = 0; - uint32_t NEXT_PC = 0; uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; uint64_t icount = 0; } reg; diff --git a/incl/iss/plugin/cycle_estimate.h b/incl/iss/plugin/cycle_estimate.h index bac42e5..0685b4a 100644 --- a/incl/iss/plugin/cycle_estimate.h +++ b/incl/iss/plugin/cycle_estimate.h @@ -76,7 +76,7 @@ public: sync_type get_sync() override { return POST_SYNC; }; - void callback(instr_info_t instr_info) override; + void callback(instr_info_t instr_info, exec_info const&) override; private: iss::instrumentation_if *arch_instr; diff --git a/incl/iss/plugin/instruction_count.h b/incl/iss/plugin/instruction_count.h index 2c79d2b..6e90cf6 100644 --- a/incl/iss/plugin/instruction_count.h +++ b/incl/iss/plugin/instruction_count.h @@ -69,7 +69,7 @@ public: sync_type get_sync() override { return POST_SYNC; }; - void callback(instr_info_t instr_info) override; + void callback(instr_info_t, exec_info const&) override; private: Json::Value root; diff --git a/src/iss/tgf_b.cpp b/src/iss/tgf_b.cpp index 17ad356..5ff17cc 100644 --- a/src/iss/tgf_b.cpp +++ b/src/iss/tgf_b.cpp @@ -41,8 +41,8 @@ using namespace iss::arch; constexpr std::array iss::arch::traits::reg_names; constexpr std::array iss::arch::traits::reg_aliases; -constexpr std::array iss::arch::traits::reg_bit_widths; -constexpr std::array iss::arch::traits::reg_byte_offsets; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; tgf_b::tgf_b() { reg.icount = 0; diff --git a/src/iss/tgf_c.cpp b/src/iss/tgf_c.cpp index f51f041..97a437e 100644 --- a/src/iss/tgf_c.cpp +++ b/src/iss/tgf_c.cpp @@ -41,8 +41,8 @@ using namespace iss::arch; constexpr std::array iss::arch::traits::reg_names; constexpr std::array iss::arch::traits::reg_aliases; -constexpr std::array iss::arch::traits::reg_bit_widths; -constexpr std::array iss::arch::traits::reg_byte_offsets; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; tgf_c::tgf_c() { reg.icount = 0; diff --git a/src/plugin/cycle_estimate.cpp b/src/plugin/cycle_estimate.cpp index 2a68c61..6abf77c 100644 --- a/src/plugin/cycle_estimate.cpp +++ b/src/plugin/cycle_estimate.cpp @@ -83,7 +83,7 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& } -void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) { +void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info const&) { 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); diff --git a/src/plugin/instruction_count.cpp b/src/plugin/instruction_count.cpp index eedb59a..2f33d7c 100644 --- a/src/plugin/instruction_count.cpp +++ b/src/plugin/instruction_count.cpp @@ -90,6 +90,6 @@ bool iss::plugin::instruction_count::registration(const char* const version, vm_ return true; } -void iss::plugin::instruction_count::callback(instr_info_t instr_info) { +void iss::plugin::instruction_count::callback(instr_info_t instr_info, exec_info const&) { rep_counts[instr_info.instr_id]++; } diff --git a/src/vm/interp/vm_tgf_b.cpp b/src/vm/interp/vm_tgf_b.cpp index b0057b9..0672a77 100644 --- a/src/vm/interp/vm_tgf_b.cpp +++ b/src/vm/interp/vm_tgf_b.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2020 MINRES Technologies GmbH + * Copyright (C) 2021 MINRES Technologies GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -149,13 +149,14 @@ protected: this->core.leave_trap(lvl); auto pc_val = super::template read_mem(traits::CSR, (lvl << 8) + 0x41); this->template get_reg(traits::NEXT_PC) = pc_val; - this->template get_reg(traits::LAST_BRANCH) = std::numeric_limits::max(); } void wait(unsigned type){ this->core.wait_until(type); } + 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){return super::template read_mem(space, addr);} inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} @@ -302,16 +303,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 0); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -335,16 +335,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 1); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -368,19 +367,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) *(X+rd) = *PC + 4; - *PC = *PC + imm; + pc_assign(*NEXT_PC) = *PC + imm; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -405,6 +403,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { int32_t new_pc = *(X+rs1) + imm; @@ -414,17 +414,14 @@ private: } else { if(rd != 0) *(X+rd) = *PC + 4; - *PC = new_pc & ~ 0x1; + pc_assign(*NEXT_PC) = new_pc & ~ 0x1; } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -449,16 +446,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) == *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) == *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -483,16 +479,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) != *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) != *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -517,16 +512,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) < *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -551,16 +545,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) >= *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -585,16 +578,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) < *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -619,16 +611,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) >= *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -653,16 +644,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = readSpace1(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -687,16 +677,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (int16_t)readSpace2(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -721,16 +710,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint32_t)readSpace4(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -755,16 +743,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -789,16 +776,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -823,16 +809,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace1(traits::MEM, *(X+rs1) + imm, (int8_t)*(X+rs2)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -857,16 +842,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace2(traits::MEM, *(X+rs1) + imm, (int16_t)*(X+rs2)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -891,16 +875,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace4(traits::MEM, *(X+rs1) + imm, *(X+rs2)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -925,16 +908,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -959,16 +941,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) < imm? 1 : 0; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -993,16 +974,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint8_t)*(X+rs1) < (uint8_t)(int32_t)imm? 1 : 0; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 20); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1027,16 +1007,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) ^ imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1061,16 +1040,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) | imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1095,16 +1073,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) & imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1129,6 +1106,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(shamt > 31) { raise(0, 0); @@ -1137,13 +1116,10 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) << shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1168,6 +1144,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(shamt > 31) { raise(0, 0); @@ -1176,13 +1154,10 @@ private: if(rd != 0) *(X+rd) = ((uint8_t)*(X+rs1)) >> shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1207,6 +1182,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(shamt > 31) { raise(0, 0); @@ -1215,13 +1192,10 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) >> shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1246,16 +1220,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 27); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1280,16 +1253,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 28); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1314,16 +1286,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 29); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1348,16 +1319,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) < *(X+rs2)? 1 : 0; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 30); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1382,16 +1352,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 31); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1416,16 +1385,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 32); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1450,16 +1418,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 33); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1484,16 +1451,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 34); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1518,16 +1484,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 35); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1552,16 +1517,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 36); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1587,16 +1551,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 37); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1621,16 +1584,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace2(traits::FENCE, traits::fencei, imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 38); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1649,16 +1611,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction raise(0, 11); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 39); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1677,16 +1638,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction raise(0, 3); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 40); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1705,16 +1665,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction leave(0); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 41); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1733,16 +1692,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction leave(1); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 42); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1761,16 +1719,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction leave(3); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 43); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1789,16 +1746,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction wait(1); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1822,19 +1778,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { writeSpace1(traits::FENCE, traits::fencevmal, (uint8_t)rs1); writeSpace1(traits::FENCE, traits::fencevmau, (uint8_t)rs2); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1859,6 +1814,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t rs_val = *(X+rs1); @@ -1872,13 +1829,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1903,6 +1857,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t xrd = readSpace4(traits::CSR, csr); @@ -1911,13 +1867,10 @@ private: if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1942,6 +1895,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t xrd = readSpace4(traits::CSR, csr); @@ -1950,13 +1905,10 @@ private: if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1981,19 +1933,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) *(X+rd) = readSpace4(traits::CSR, csr); writeSpace4(traits::CSR, csr, (uint32_t)zimm); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2018,6 +1969,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t res = readSpace4(traits::CSR, csr); @@ -2025,13 +1978,10 @@ private: if(rd != 0) *(X+rd) = res; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2056,6 +2006,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t res = readSpace4(traits::CSR, csr); @@ -2063,13 +2015,10 @@ private: if(zimm != 0) writeSpace4(traits::CSR, csr, res & ~ ((uint32_t)zimm)); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); diff --git a/src/vm/interp/vm_tgf_c.cpp b/src/vm/interp/vm_tgf_c.cpp index a9ff8e6..7ce27e4 100644 --- a/src/vm/interp/vm_tgf_c.cpp +++ b/src/vm/interp/vm_tgf_c.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2020 MINRES Technologies GmbH + * Copyright (C) 2021 MINRES Technologies GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -149,13 +149,14 @@ protected: this->core.leave_trap(lvl); auto pc_val = super::template read_mem(traits::CSR, (lvl << 8) + 0x41); this->template get_reg(traits::NEXT_PC) = pc_val; - this->template get_reg(traits::LAST_BRANCH) = std::numeric_limits::max(); } void wait(unsigned type){ this->core.wait_until(type); } + 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){return super::template read_mem(space, addr);} inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} @@ -374,16 +375,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 0); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -407,16 +407,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 1); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -440,19 +439,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) *(X+rd) = *PC + 4; - *PC = *PC + imm; + pc_assign(*NEXT_PC) = *PC + imm; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -477,20 +475,19 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { int32_t new_pc = *(X+rs1) + imm; if(rd != 0) *(X+rd) = *PC + 4; - *PC = new_pc & ~ 0x1; + pc_assign(*NEXT_PC) = new_pc & ~ 0x1; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -515,16 +512,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) == *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) == *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -549,16 +545,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) != *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) != *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -583,16 +578,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) < *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -617,16 +611,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) >= *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -651,16 +644,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) < *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -685,16 +677,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction - if(*(X+rs1) >= *(X+rs2)) *PC = *PC + imm; + if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -719,16 +710,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = readSpace1(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -753,16 +743,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (int16_t)readSpace2(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -787,16 +776,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint32_t)readSpace4(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -821,16 +809,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -855,16 +842,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -889,16 +875,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace1(traits::MEM, *(X+rs1) + imm, (int8_t)*(X+rs2)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -923,16 +908,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace2(traits::MEM, *(X+rs1) + imm, (int16_t)*(X+rs2)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -957,16 +941,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace4(traits::MEM, *(X+rs1) + imm, *(X+rs2)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -991,16 +974,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1025,16 +1007,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) < imm? 1 : 0; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1059,16 +1040,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint8_t)*(X+rs1) < (uint8_t)(int32_t)imm? 1 : 0; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 20); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1093,16 +1073,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) ^ imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1127,16 +1106,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) | imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1161,16 +1139,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) & imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1195,6 +1172,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(shamt > 31) { raise(0, 0); @@ -1203,13 +1182,10 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) << shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1234,6 +1210,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(shamt > 31) { raise(0, 0); @@ -1242,13 +1220,10 @@ private: if(rd != 0) *(X+rd) = ((uint8_t)*(X+rs1)) >> shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1273,6 +1248,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(shamt > 31) { raise(0, 0); @@ -1281,13 +1258,10 @@ private: if(rd != 0) *(X+rd) = *(X+rs1) >> shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1312,16 +1286,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 27); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1346,16 +1319,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 28); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1380,16 +1352,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 29); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1414,16 +1385,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) < *(X+rs2)? 1 : 0; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 30); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1448,16 +1418,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 31); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1482,16 +1451,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 32); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1516,16 +1484,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 33); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1550,16 +1517,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 34); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1584,16 +1550,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 35); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1618,16 +1583,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 36); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1653,16 +1617,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 37); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1687,16 +1650,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction writeSpace2(traits::FENCE, traits::fencei, imm); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 38); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1715,16 +1677,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction raise(0, 11); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 39); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1743,16 +1704,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction raise(0, 3); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 40); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1771,16 +1731,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction leave(0); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 41); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1799,16 +1758,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction leave(1); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 42); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1827,16 +1785,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction leave(3); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 43); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1855,16 +1812,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction wait(1); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1888,19 +1844,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { writeSpace1(traits::FENCE, traits::fencevmal, (uint8_t)rs1); writeSpace1(traits::FENCE, traits::fencevmau, (uint8_t)rs2); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1925,6 +1880,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t rs_val = *(X+rs1); @@ -1938,13 +1895,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -1969,6 +1923,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t xrd = readSpace4(traits::CSR, csr); @@ -1977,13 +1933,10 @@ private: if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2008,6 +1961,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t xrd = readSpace4(traits::CSR, csr); @@ -2016,13 +1971,10 @@ private: if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2047,19 +1999,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) *(X+rd) = readSpace4(traits::CSR, csr); writeSpace4(traits::CSR, csr, (uint32_t)zimm); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2084,6 +2035,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t res = readSpace4(traits::CSR, csr); @@ -2091,13 +2044,10 @@ private: if(rd != 0) *(X+rd) = res; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2122,6 +2072,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { uint32_t res = readSpace4(traits::CSR, csr); @@ -2129,13 +2081,10 @@ private: if(zimm != 0) writeSpace4(traits::CSR, csr, res & ~ ((uint32_t)zimm)); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2160,6 +2109,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) { @@ -2168,13 +2119,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2199,6 +2147,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) { @@ -2207,13 +2157,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2238,6 +2185,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) { @@ -2246,13 +2195,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2277,6 +2223,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) { @@ -2285,13 +2233,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2316,6 +2261,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) { @@ -2328,13 +2275,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2359,6 +2303,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) { @@ -2367,13 +2313,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2398,6 +2341,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) { @@ -2410,13 +2355,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2441,6 +2383,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 4; // execute instruction { if(rd != 0) { @@ -2449,13 +2393,10 @@ private: } } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2479,19 +2420,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { if(imm == 0) raise(0, 2); *(X+(rd + 8)) = *(X+2) + imm; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2516,19 +2456,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint32_t offs = *(X+(rs1 + 8)) + uimm; *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, offs); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2553,19 +2492,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t offs = *(X+(rs1 + 8)) + uimm; writeSpace4(traits::MEM, offs, *(X+(rs2 + 8))); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2589,16 +2527,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction *(X+rs1) = (int8_t)*(X+rs1) + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2617,17 +2554,16 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2650,19 +2586,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { *(X+1) = *PC + 2; - *PC = (int8_t)*PC + imm; + pc_assign(*NEXT_PC) = (int8_t)*PC + imm; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2686,19 +2621,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { if(rd == 0) raise(0, 2); *(X+rd) = imm; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2722,6 +2656,8 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { if(rd == 0) raise(0, 2); @@ -2729,13 +2665,10 @@ private: *(X+rd) = imm; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2758,16 +2691,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction *(X+2) = (int8_t)*(X+2) + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2791,19 +2723,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = *(X+rs1_idx) << shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2827,19 +2758,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = ((int8_t)*(X+rs1_idx)) >> shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2863,19 +2793,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = *(X+rs1_idx) & imm; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2899,19 +2828,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8)); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2935,19 +2863,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8)); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -2971,19 +2898,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8)); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3007,19 +2933,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8)); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3042,16 +2967,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction - *PC = (int8_t)*PC + imm; + pc_assign(*NEXT_PC) = (int8_t)*PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3075,16 +2999,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction - if(*(X+(rs1 + 8)) == 0) *PC = (int8_t)*PC + imm; + if(*(X+(rs1 + 8)) == 0) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3108,16 +3031,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction - if(*(X+(rs1 + 8)) != 0) *PC = (int8_t)*PC + imm; + if(*(X+(rs1 + 8)) != 0) pc_assign(*NEXT_PC) = *PC + imm; // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3141,19 +3063,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { if(rs1 == 0) raise(0, 2); *(X+rs1) = *(X+rs1) << shamt; } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3177,19 +3098,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t offs = *(X+2) + uimm; *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3213,16 +3133,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction *(X+rd) = *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3245,16 +3164,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction - *PC = *(X+rs1); + pc_assign(*NEXT_PC) = *(X+rs1); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3278,16 +3196,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction *(X+rd) = *(X+rd) + *(X+rs2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3310,19 +3227,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { *(X+1) = *PC + 2; - *PC = *(X+rs1); + pc_assign(*NEXT_PC) = *(X+rs1); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3341,16 +3257,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction raise(0, 3); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3374,19 +3289,18 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction { uint8_t offs = *(X+2) + uimm; writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); } // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); @@ -3405,16 +3319,15 @@ private: // prepare execution uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); 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 + 2; // execute instruction raise(0, 2); // post execution stuff - super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); // trap check if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); super::core.enter_trap(trap_state, pc.val); } pc.val=super::template get_reg(arch::traits::NEXT_PC); diff --git a/src/vm/tcc/vm_tgf_b.cpp b/src/vm/tcc/vm_tgf_b.cpp index b65c2a1..93d4177 100644 --- a/src/vm/tcc/vm_tgf_b.cpp +++ b/src/vm/tcc/vm_tgf_b.cpp @@ -377,7 +377,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 2); gen_trap_check(tu); @@ -424,7 +423,6 @@ private: new_pc_val, tu.l_not(tu.constant(0x1, 32U))), 32); tu.store(PC_val_v, traits::NEXT_PC); - tu.store(tu.constant(std::numeric_limits::max(), 32U), traits::LAST_BRANCH); tu.close_scope(); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 3); @@ -466,7 +464,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 4); gen_trap_check(tu); @@ -507,7 +504,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 5); gen_trap_check(tu); @@ -552,7 +548,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 6); gen_trap_check(tu); @@ -597,7 +592,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 7); gen_trap_check(tu); @@ -638,7 +632,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 8); gen_trap_check(tu); @@ -679,7 +672,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 9); gen_trap_check(tu); @@ -1621,7 +1613,6 @@ private: tu.constant(1, 64U), tu.trunc(tu.constant(imm, 32U), 32)); tu.close_scope(); - tu.store(tu.constant(std::numeric_limits::max(), 32),traits::LAST_BRANCH); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 38); gen_trap_check(tu); @@ -2055,13 +2046,11 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, template void vm_impl::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) { tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id); - tu.store(tu.constant(std::numeric_limits::max(), 32),traits::LAST_BRANCH); } template void vm_impl::gen_leave_trap(tu_builder& tu, unsigned lvl) { tu("leave_trap(core_ptr, {});", lvl); tu.store(tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN),traits::NEXT_PC); - tu.store(tu.constant(std::numeric_limits::max(), 32),traits::LAST_BRANCH); } template void vm_impl::gen_wait(tu_builder& tu, unsigned type) { @@ -2070,7 +2059,6 @@ template void vm_impl::gen_wait(tu_builder& tu, unsigned t template void vm_impl::gen_trap_behavior(tu_builder& tu) { tu("trap_entry:"); tu("enter_trap(core_ptr, *trap_state, *pc);"); - tu.store(tu.constant(std::numeric_limits::max(),32),traits::LAST_BRANCH); tu("return *next_pc;"); } diff --git a/src/vm/tcc/vm_tgf_c.cpp b/src/vm/tcc/vm_tgf_c.cpp index c32d982..79e4449 100644 --- a/src/vm/tcc/vm_tgf_c.cpp +++ b/src/vm/tcc/vm_tgf_c.cpp @@ -449,7 +449,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 2); gen_trap_check(tu); @@ -487,7 +486,6 @@ private: new_pc_val, tu.l_not(tu.constant(0x1, 32U))), 32); tu.store(PC_val_v, traits::NEXT_PC); - tu.store(tu.constant(std::numeric_limits::max(), 32U), traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 3); gen_trap_check(tu); @@ -528,7 +526,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 4); gen_trap_check(tu); @@ -569,7 +566,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 5); gen_trap_check(tu); @@ -614,7 +610,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 6); gen_trap_check(tu); @@ -659,7 +654,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 7); gen_trap_check(tu); @@ -700,7 +694,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 8); gen_trap_check(tu); @@ -741,7 +734,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 9); gen_trap_check(tu); @@ -1683,7 +1675,6 @@ private: tu.constant(1, 64U), tu.trunc(tu.constant(imm, 32U), 32)); tu.close_scope(); - tu.store(tu.constant(std::numeric_limits::max(), 32),traits::LAST_BRANCH); gen_set_pc(tu, pc, traits::NEXT_PC); vm_base::gen_sync(tu, POST_SYNC, 38); gen_trap_check(tu); @@ -2562,7 +2553,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 65); gen_trap_check(tu); @@ -2868,7 +2858,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 76); gen_trap_check(tu); @@ -2908,7 +2897,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 77); gen_trap_check(tu); @@ -2948,7 +2936,6 @@ private: auto is_cont_v = tu.choose( tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32U, true), tu.constant(pc.val, 32U)), tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(is_cont_v, traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 78); gen_trap_check(tu); @@ -3055,7 +3042,6 @@ private: tu.open_scope(); auto PC_val_v = tu.assignment("PC_val", tu.load(rs1 + traits::X0, 0), 32); tu.store(PC_val_v, traits::NEXT_PC); - tu.store(tu.constant(std::numeric_limits::max(), 32U), traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 82); gen_trap_check(tu); @@ -3108,7 +3094,6 @@ private: tu.constant(2, 32U)), 1 + traits::X0); auto PC_val_v = tu.assignment("PC_val", tu.load(rs1 + traits::X0, 0), 32); tu.store(PC_val_v, traits::NEXT_PC); - tu.store(tu.constant(std::numeric_limits::max(), 32U), traits::LAST_BRANCH); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC, 84); gen_trap_check(tu); @@ -3247,13 +3232,11 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, template void vm_impl::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) { tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id); - tu.store(tu.constant(std::numeric_limits::max(), 32),traits::LAST_BRANCH); } template void vm_impl::gen_leave_trap(tu_builder& tu, unsigned lvl) { tu("leave_trap(core_ptr, {});", lvl); tu.store(tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN),traits::NEXT_PC); - tu.store(tu.constant(std::numeric_limits::max(), 32),traits::LAST_BRANCH); } template void vm_impl::gen_wait(tu_builder& tu, unsigned type) { @@ -3262,7 +3245,6 @@ template void vm_impl::gen_wait(tu_builder& tu, unsigned t template void vm_impl::gen_trap_behavior(tu_builder& tu) { tu("trap_entry:"); tu("enter_trap(core_ptr, *trap_state, *pc);"); - tu.store(tu.constant(std::numeric_limits::max(),32),traits::LAST_BRANCH); tu("return *next_pc;"); }