diff --git a/gen_input/TGC_C.core_desc b/gen_input/TGC_C.core_desc index 72f549d..8377d41 100644 --- a/gen_input/TGC_C.core_desc +++ b/gen_input/TGC_C.core_desc @@ -1,13 +1,13 @@ -import "RV32I.core_desc" -import "RVM.core_desc" -import "RVC.core_desc" +import "ISA/RV32I.core_desc" +import "ISA/RVM.core_desc" +import "ISA/RVC.core_desc" Core TGC_C provides RV32I, Zicsr, Zifencei, RV32M, RV32IC { architectural_state { XLEN=32; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - unsigned MISA_VAL = 0b01000000000000000001000100000100; - unsigned MARCHID_VAL = 0x80000003; + unsigned int MISA_VAL = 0b01000000000000000001000100000100; + unsigned int MARCHID_VAL = 0x80000003; } } diff --git a/gen_input/templates/CORENAME.cpp.gtl b/gen_input/templates/CORENAME.cpp.gtl index 3a06133..b7468c7 100644 --- a/gen_input/templates/CORENAME.cpp.gtl +++ b/gen_input/templates/CORENAME.cpp.gtl @@ -62,8 +62,8 @@ void ${coreDef.name.toLowerCase()}::reset(uint64_t address) { reg.PC=address; reg.NEXT_PC=reg.PC; reg.PRIV=0x3; - trap_state=0; - icount=0; + reg.trap_state=0; + reg.icount=0; } uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { diff --git a/gen_input/templates/CORENAME.h.gtl b/gen_input/templates/CORENAME.h.gtl index 563631f..9c8082e 100644 --- a/gen_input/templates/CORENAME.h.gtl +++ b/gen_input/templates/CORENAME.h.gtl @@ -136,7 +136,7 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { uint8_t* get_regs_base_ptr() override; - inline uint64_t get_icount() { return icount; } + inline uint64_t get_icount() { return reg.icount; } inline bool should_stop() { return interrupt_sim; } @@ -154,7 +154,7 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } - inline uint32_t get_last_branch() { return last_branch; } + inline uint32_t get_last_branch() { return reg.last_branch; } #pragma pack(push, 1) @@ -170,12 +170,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { uint32_t last_branch = 0; } reg; #pragma pack(pop) - uint32_t trap_state = 0, pending_trap = 0; - uint64_t icount = 0; - uint64_t cycle = 0; - uint64_t instret = 0; - uint32_t instruction = 0; - uint32_t last_branch = 0; std::array addr_mode; uint64_t interrupt_sim=0; diff --git a/gen_input/templates/CORENAME_instr.yaml.gtl b/gen_input/templates/CORENAME_instr.yaml.gtl index 9b29705..542fed6 100644 --- a/gen_input/templates/CORENAME_instr.yaml.gtl +++ b/gen_input/templates/CORENAME_instr.yaml.gtl @@ -13,5 +13,8 @@ ${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %> - ${it.instruction.name}: encoding: ${it.encoding} mask: ${it.mask}<%if(it.attributes.size) {%> - attributes: ${it.attributes}<%}}}%> + attributes: ${it.attributes}<%}%> + size: ${it.length} + branch: ${it.modifiesPC} + delay: ${it.isConditional?"[1,1]":"1"}<%}}%> diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 7b26430..ef645bf 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -121,7 +121,7 @@ protected: inline void raise(uint16_t trap_id, uint16_t cause){ auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id; - this->core.trap_state = trap_val; + this->core.reg.trap_state = trap_val; this->template get_reg(traits::NEXT_PC) = std::numeric_limits::max(); } @@ -244,16 +244,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto pc=start; auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - auto& trap_state = this->core.trap_state; - auto& icount = this->core.icount; - auto& cycle = this->core.cycle; - auto& instret = this->core.instret; - auto& instr = this->core.instruction; + auto& trap_state = this->core.reg.trap_state; + auto& icount = this->core.reg.icount; + auto& cycle = this->core.reg.cycle; + auto& instret = this->core.reg.instret; + auto& instr = this->core.reg.instruction; // we fetch at max 4 byte, alignment is 2 auto *const data = reinterpret_cast(&instr); while(!this->core.should_stop() && - !(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){ + !(is_count_limit_enabled(cond) && icount >= icount_limit)){ if(fetch_ins(pc, data)!=iss::Ok){ this->do_sync(POST_SYNC, std::numeric_limits::max()); pc.val = super::core.enter_trap(std::numeric_limits::max(), pc.val, 0); @@ -262,7 +262,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co (instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0' auto inst_id = decode_inst_id(instr); // pre execution stuff - this->core.last_branch = 0; + this->core.reg.last_branch = 0; if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast(inst_id)); switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %> case arch::traits::opcode_e::${instr.name}: { @@ -289,8 +289,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // post execution stuff process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast(inst_id)); - // if(!this->core.trap_state) // update trap state if there is a pending interrupt - // this->core.trap_state = this->core.pending_trap; + // if(!this->core.reg.trap_state) // update trap state if there is a pending interrupt + // this->core.reg.trap_state = this->core.reg.pending_trap; // trap check if(trap_state!=0){ super::core.enter_trap(trap_state, pc.val, instr); @@ -301,7 +301,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co cycle++; pc.val=*NEXT_PC; this->core.reg.PC = this->core.reg.NEXT_PC; - this->core.trap_state = this->core.pending_trap; + this->core.reg.trap_state = this->core.reg.pending_trap; } } return pc; diff --git a/gen_input/templates/tcc/vm-vm_CORENAME.cpp.gtl b/gen_input/templates/tcc/CORENAME.cpp.gtl similarity index 96% rename from gen_input/templates/tcc/vm-vm_CORENAME.cpp.gtl rename to gen_input/templates/tcc/CORENAME.cpp.gtl index bd0d7fa..9ce0e26 100644 --- a/gen_input/templates/tcc/vm-vm_CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/CORENAME.cpp.gtl @@ -256,20 +256,20 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, // we fetch at max 4 byte, alignment is 2 enum {TRAP_ID=1<<16}; code_word_t insn = 0; - const typename traits::addr_t upper_bits = ~traits::PGMASK; + // const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); auto *const data = (uint8_t *)&insn; paddr = this->core.v2p(pc); - if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary - auto res = this->core.read(paddr, 2, data); - if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); - if ((insn & 0x3) == 0x3) { // this is a 32bit instruction - res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); - } - } else { +// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary +// auto res = this->core.read(paddr, 2, data); +// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); +// if ((insn & 0x3) == 0x3) { // this is a 32bit instruction +// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); +// } +// } else { auto res = this->core.read(paddr, 4, data); if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); - } +// } if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' // curr pc on stack ++inst_cnt; diff --git a/gen_input/templates/tcc/CORENAME_cyles.txt.gtl b/gen_input/templates/tcc/CORENAME_cyles.txt.gtl deleted file mode 100644 index 3a1ad8e..0000000 --- a/gen_input/templates/tcc/CORENAME_cyles.txt.gtl +++ /dev/null @@ -1,9 +0,0 @@ -{ - "${coreDef.name}" : [<%instructions.eachWithIndex{instr,index -> %>${index==0?"":","} - { - "name" : "${instr.name}", - "size" : ${instr.length}, - "delay" : ${generator.hasAttribute(instr.instruction, com.minres.coredsl.coreDsl.InstrAttribute.COND)?[1,1]:1} - }<%}%> - ] -} \ No newline at end of file diff --git a/gen_input/templates/tcc/incl-CORENAME.h.gtl b/gen_input/templates/tcc/incl-CORENAME.h.gtl deleted file mode 100644 index 0a5b99f..0000000 --- a/gen_input/templates/tcc/incl-CORENAME.h.gtl +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2017, 2018 MINRES Technologies GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - *******************************************************************************/ - -<% -import com.minres.coredsl.coreDsl.Register -import com.minres.coredsl.coreDsl.RegisterFile -import com.minres.coredsl.coreDsl.RegisterAlias -def getTypeSize(size){ - if(size > 32) 64 else if(size > 16) 32 else if(size > 8) 16 else 8 -} -def getOriginalName(reg){ - if( reg.original instanceof RegisterFile) { - if( reg.index != null ) { - return reg.original.name+generator.generateHostCode(reg.index) - } else { - return reg.original.name - } - } else if(reg.original instanceof Register){ - return reg.original.name - } -} -def getRegisterNames(){ - def regNames = [] - allRegs.each { reg -> - if( reg instanceof RegisterFile) { - (reg.range.right..reg.range.left).each{ - regNames+=reg.name.toLowerCase()+it - } - } else if(reg instanceof Register){ - regNames+=reg.name.toLowerCase() - } - } - return regNames -} -def getRegisterAliasNames(){ - def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]} - return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg -> - if( reg instanceof RegisterFile) { - return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() } - } else if(reg instanceof Register){ - regMap[reg.name]?:reg.name.toLowerCase() - } - }.flatten() -} -%> -#ifndef _${coreDef.name.toUpperCase()}_H_ -#define _${coreDef.name.toUpperCase()}_H_ - -#include -#include -#include -#include - -namespace iss { -namespace arch { - -struct ${coreDef.name.toLowerCase()}; - -template <> struct traits<${coreDef.name.toLowerCase()}> { - - constexpr static char const* const core_type = "${coreDef.name}"; - - static constexpr std::array reg_names{ - {"${getRegisterNames().join("\", \"")}"}}; - - static constexpr std::array reg_aliases{ - {"${getRegisterAliasNames().join("\", \"")}"}}; - - enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}}; - - constexpr static unsigned FP_REGS_SIZE = ${coreDef.constants.find {it.name=='FLEN'}?.value?:0}; - - enum reg_e {<% - allRegs.each { reg -> - if( reg instanceof RegisterFile) { - (reg.range.right..reg.range.left).each{%> - ${reg.name}${it},<% - } - } else if(reg instanceof Register){ %> - ${reg.name},<% - } - }%> - NUM_REGS, - NEXT_${pc.name}=NUM_REGS, - TRAP_STATE, - PENDING_TRAP, - MACHINE_STATE, - LAST_BRANCH, - ICOUNT<% - allRegs.each { reg -> - if(reg instanceof RegisterAlias){ def aliasname=getOriginalName(reg)%>, - ${reg.name} = ${aliasname}<% - } - }%> - }; - - using reg_t = uint${regDataWidth}_t; - - using addr_t = uint${addrDataWidth}_t; - - using code_word_t = uint${addrDataWidth}_t; //TODO: check removal - - using virt_addr_t = iss::typed_addr_t; - - using phys_addr_t = iss::typed_addr_t; - - static constexpr std::array reg_bit_widths{ - {${regSizes.join(",")}}}; - - static constexpr std::array reg_byte_offsets{ - {${regOffsets.join(",")}}}; - - static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); - - enum sreg_flag_e { FLAGS }; - - enum mem_type_e { ${allSpaces.collect{s -> s.name}.join(', ')} }; -}; - -struct ${coreDef.name.toLowerCase()}: public arch_if { - - using virt_addr_t = typename traits<${coreDef.name.toLowerCase()}>::virt_addr_t; - using phys_addr_t = typename traits<${coreDef.name.toLowerCase()}>::phys_addr_t; - using reg_t = typename traits<${coreDef.name.toLowerCase()}>::reg_t; - using addr_t = typename traits<${coreDef.name.toLowerCase()}>::addr_t; - - ${coreDef.name.toLowerCase()}(); - ~${coreDef.name.toLowerCase()}(); - - void reset(uint64_t address=0) override; - - uint8_t* get_regs_base_ptr() override; - /// deprecated - void get_reg(short idx, std::vector& value) override {} - void set_reg(short idx, const std::vector& value) override {} - /// deprecated - bool get_flag(int flag) override {return false;} - void set_flag(int, bool value) override {}; - /// deprecated - void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; - - inline uint64_t get_icount() { return reg.icount; } - - inline bool should_stop() { return interrupt_sim; } - - inline uint64_t stop_code() { return interrupt_sim; } - - inline phys_addr_t v2p(const iss::addr_t& addr){ - if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL || - addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { - return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask); - } else - return virt2phys(addr); - } - - virtual phys_addr_t virt2phys(const iss::addr_t& addr); - - virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } - - inline uint32_t get_last_branch() { return reg.last_branch; } - -protected: - struct ${coreDef.name}_regs {<% - allRegs.each { reg -> - if( reg instanceof RegisterFile) { - (reg.range.right..reg.range.left).each{%> - uint${generator.getSize(reg)}_t ${reg.name}${it} = 0;<% - } - } else if(reg instanceof Register){ %> - uint${generator.getSize(reg)}_t ${reg.name} = 0;<% - } - }%> - uint${generator.getSize(pc)}_t NEXT_${pc.name} = 0; - uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; - uint64_t icount = 0; - } reg; - - std::array addr_mode; - - uint64_t interrupt_sim=0; -<% -def fcsr = allRegs.find {it.name=='FCSR'} -if(fcsr != null) {%> - uint${generator.getSize(fcsr)}_t get_fcsr(){return reg.FCSR;} - void set_fcsr(uint${generator.getSize(fcsr)}_t val){reg.FCSR = val;} -<%} else { %> - uint32_t get_fcsr(){return 0;} - void set_fcsr(uint32_t val){} -<%}%> -}; - -} -} -#endif /* _${coreDef.name.toUpperCase()}_H_ */ diff --git a/gen_input/templates/tcc/src-CORENAME.cpp.gtl b/gen_input/templates/tcc/src-CORENAME.cpp.gtl deleted file mode 100644 index 8ed478f..0000000 --- a/gen_input/templates/tcc/src-CORENAME.cpp.gtl +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2017, 2018 MINRES Technologies GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - *******************************************************************************/ - <% -import com.minres.coredsl.coreDsl.Register -import com.minres.coredsl.coreDsl.RegisterFile -import com.minres.coredsl.coreDsl.RegisterAlias -def getOriginalName(reg){ - if( reg.original instanceof RegisterFile) { - if( reg.index != null ) { - return reg.original.name+generator.generateHostCode(reg.index) - } else { - return reg.original.name - } - } else if(reg.original instanceof Register){ - return reg.original.name - } -} -def getRegisterNames(){ - def regNames = [] - allRegs.each { reg -> - if( reg instanceof RegisterFile) { - (reg.range.right..reg.range.left).each{ - regNames+=reg.name.toLowerCase()+it - } - } else if(reg instanceof Register){ - regNames+=reg.name.toLowerCase() - } - } - return regNames -} -def getRegisterAliasNames(){ - def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]} - return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg -> - if( reg instanceof RegisterFile) { - return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() } - } else if(reg instanceof Register){ - regMap[reg.name]?:reg.name.toLowerCase() - } - }.flatten() -} -%> -#include "util/ities.h" -#include -#include -#include -#include -#include - -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; - -${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { - reg.icount = 0; -} - -${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default; - -void ${coreDef.name.toLowerCase()}::reset(uint64_t address) { - for(size_t i=0; i::NUM_REGS; ++i) set_reg(i, std::vector(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0)); - reg.PC=address; - reg.NEXT_PC=reg.PC; - reg.trap_state=0; - reg.machine_state=0x3; - reg.icount=0; -} - -uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { - return reinterpret_cast(®); -} - -${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &pc) { - return phys_addr_t(pc); // change logical address to physical address -} - diff --git a/src/iss/arch/riscv_hart_m_p.h b/src/iss/arch/riscv_hart_m_p.h index 1462848..1111146 100644 --- a/src/iss/arch/riscv_hart_m_p.h +++ b/src/iss/arch/riscv_hart_m_p.h @@ -280,7 +280,7 @@ public: void disass_output(uint64_t pc, const std::string instr) override { CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [s:0x{:x};c:{}]", - pc, instr, (reg_t)state.mstatus, this->icount + cycle_offset); + pc, instr, (reg_t)state.mstatus, this->reg.icount + cycle_offset); }; iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; } @@ -308,17 +308,17 @@ protected: uint64_t get_next_pc() override { return arch.reg.NEXT_PC; }; - uint64_t get_instr_word() override { return arch.instruction; } + uint64_t get_instr_word() override { return arch.reg.instruction; } - uint64_t get_instr_count() override { return arch.icount; } + uint64_t get_instr_count() override { return arch.reg.icount; } - uint64_t get_pendig_traps() override { return arch.trap_state; } + uint64_t get_pendig_traps() override { return arch.reg.trap_state; } - uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; } + uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; } void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; }; - bool is_branch_taken() override { return arch.last_branch; }; + bool is_branch_taken() override { return arch.reg.last_branch; }; riscv_hart_m_p &arch; }; @@ -657,12 +657,12 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { fault_data = addr; if (is_debug(access)) throw trap_access(0, addr); - this->trap_state = (1UL << 31); // issue trap 0 + this->reg.trap_state = (1UL << 31); // issue trap 0 return iss::Err; } try { if(!is_debug(access) && (addr&(alignment-1))){ - this->trap_state = (1UL << 31) | 4<<16; + this->reg.trap_state = (1UL << 31) | 4<<16; fault_data=addr; return iss::Err; } @@ -681,12 +681,12 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce res = hart_mem_rd_delegate( phys_addr, length, data); } if (unlikely(res != iss::Ok)){ - this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault + this->reg.trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault fault_data=addr; } return res; } catch (trap_access &ta) { - this->trap_state = (1UL << 31) | ta.id; + this->reg.trap_state = (1UL << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -712,7 +712,7 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce } return iss::Ok; } catch (trap_access &ta) { - this->trap_state = (1UL << 31) | ta.id; + this->reg.trap_state = (1UL << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -750,12 +750,12 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) { fault_data = addr; if (access && iss::access_type::DEBUG) throw trap_access(0, addr); - this->trap_state = (1UL << 31); // issue trap 0 + this->reg.trap_state = (1UL << 31); // issue trap 0 return iss::Err; } try { if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){ - this->trap_state = (1UL << 31) | 6<<16; + this->reg.trap_state = (1UL << 31) | 6<<16; fault_data=addr; return iss::Err; } @@ -774,12 +774,12 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc res = write_mem( phys_addr, length, data); } if (unlikely(res != iss::Ok)) { - this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) + this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) fault_data=addr; } return res; } catch (trap_access &ta) { - this->trap_state = (1UL << 31) | ta.id; + this->reg.trap_state = (1UL << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -839,7 +839,7 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc } return iss::Ok; } catch (trap_access &ta) { - this->trap_state = (1UL << 31) | ta.id; + this->reg.trap_state = (1UL << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -885,7 +885,7 @@ template iss::status riscv_hart_m_p } template iss::status riscv_hart_m_p::read_cycle(unsigned addr, reg_t &val) { - auto cycle_val = this->icount + cycle_offset; + auto cycle_val = this->reg.icount + cycle_offset; if (addr == mcycle) { val = static_cast(cycle_val); } else if (addr == mcycleh) { @@ -904,35 +904,35 @@ template iss::status riscv_hart_m_p mcycle_csr = (static_cast(val)<<32) + (mcycle_csr & 0xffffffff); } } - cycle_offset = mcycle_csr-this->icount; // TODO: relying on wrap-around + cycle_offset = mcycle_csr-this->reg.icount; // TODO: relying on wrap-around return iss::Ok; } template iss::status riscv_hart_m_p::read_instret(unsigned addr, reg_t &val) { if ((addr&0xff) == (minstret&0xff)) { - val = static_cast(this->instret); + val = static_cast(this->reg.instret); } else if ((addr&0xff) == (minstreth&0xff)) { - val = static_cast(this->instret >> 32); + val = static_cast(this->reg.instret >> 32); } return iss::Ok; } template iss::status riscv_hart_m_p::write_instret(unsigned addr, reg_t val) { if (sizeof(typename traits::reg_t) != 4) { - this->instret = static_cast(val); + this->reg.instret = static_cast(val); } else { if ((addr&0xff) == (minstret&0xff)) { - this->instret = (this->instret & 0xffffffff00000000) + val; + this->reg.instret = (this->reg.instret & 0xffffffff00000000) + val; } else { - this->instret = (static_cast(val)<<32) + (this->instret & 0xffffffff); + this->reg.instret = (static_cast(val)<<32) + (this->reg.instret & 0xffffffff); } } - this->instret--; + this->reg.instret--; return iss::Ok; } template iss::status riscv_hart_m_p::read_time(unsigned addr, reg_t &val) { - uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052; + uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052; if (addr == time) { val = static_cast(time_val); } else if (addr == timeh) { @@ -1074,18 +1074,6 @@ iss::status riscv_hart_m_p::write_xtvt(unsigned addr, reg_t val) { template iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { switch (paddr.val) { - case 0x0200BFF8: { // CLINT base, mtime reg - if (sizeof(reg_t) < length) return iss::Err; - reg_t time_val; - this->read_csr(time, time_val); - std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data); - } break; - case 0x10008000: { - const mem_type::page_type &p = mem(paddr.val / mem.page_size); - uint64_t offs = paddr.val & mem.page_addr_mask; - std::copy(p.data() + offs, p.data() + offs + length, data); - if (this->icount > 30000) data[3] |= 0x80; - } break; default: { for(auto offs=0U; offs::read_mem(phys_addr_t paddr, unsigned len template iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { switch (paddr.val) { - case 0x10013000: // UART0 base, TXFIFO reg - case 0x10023000: // UART1 base, TXFIFO reg - uart_buf << (char)data[0]; + case 0xFFFF0000: // UART0 base, TXFIFO reg if (((char)data[0]) == '\n' || data[0] == 0) { - LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send '"<>12)&0x3)<<" send '"<::write_mem(phys_addr_t paddr, unsigned le LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar << "), stopping simulation"; } - this->trap_state=std::numeric_limits::max(); + this->reg.trap_state=std::numeric_limits::max(); this->interrupt_sim=hostvar; break; //throw(iss::simulation_stopped(hostvar)); @@ -1227,7 +1199,7 @@ template void riscv_hart_m_p::check enabled_interrupts >>= 1; res++; } - this->pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id + this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id } } @@ -1275,7 +1247,7 @@ template uint64_t riscv_hart_m_p::e fault_data = 0; } else { csr[mepc] = this->reg.NEXT_PC & get_pc_mask(); // store next address if interrupt - this->pending_trap = 0; + this->reg.pending_trap = 0; } csr[mcause] = (trap_id << (traits::XLEN-1)) + cause; // update mstatus @@ -1305,7 +1277,7 @@ template uint64_t riscv_hart_m_p::e } // reset trap state this->reg.PRIV = new_priv; - this->trap_state = 0; + this->reg.trap_state = 0; std::array buffer; #if defined(_MSC_VER) sprintf(buffer.data(), "0x%016llx", addr); @@ -1326,7 +1298,7 @@ template uint64_t riscv_hart_m_p::l this->reg.NEXT_PC = csr[mepc] & get_pc_mask(); CLOG(INFO, disass) << "Executing xRET"; check_interrupt(); - this->trap_state = this->pending_trap; + this->reg.trap_state = this->reg.pending_trap; return this->reg.NEXT_PC; } diff --git a/src/iss/arch/riscv_hart_msu_vp.h b/src/iss/arch/riscv_hart_msu_vp.h index 5936329..49d1363 100644 --- a/src/iss/arch/riscv_hart_msu_vp.h +++ b/src/iss/arch/riscv_hart_msu_vp.h @@ -307,7 +307,7 @@ public: void disass_output(uint64_t pc, const std::string instr) override { CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", - pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->icount + cycle_offset); + pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.icount + cycle_offset); }; iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; } @@ -607,12 +607,12 @@ iss::status riscv_hart_msu_vp::read(const address_type type, const access_ if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { fault_data = addr; if (access && iss::access_type::DEBUG) throw trap_access(0, addr); - this->trap_state = (1 << 31); // issue trap 0 + this->reg.trap_state = (1 << 31); // issue trap 0 return iss::Err; } try { if(!is_debug(access) && (addr&(alignment-1))){ - this->trap_state = 1<<31 | 4<<16; + this->reg.trap_state = 1<<31 | 4<<16; fault_data=addr; return iss::Err; } @@ -631,12 +631,12 @@ iss::status riscv_hart_msu_vp::read(const address_type type, const access_ read_mem( BASE::v2p(phys_addr_t{access, space, addr}), length, data): read_mem( BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); if (unlikely(res != iss::Ok)){ - this->trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault + this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault fault_data=addr; } return res; } catch (trap_access &ta) { - this->trap_state = (1 << 31) | ta.id; + this->reg.trap_state = (1 << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -652,7 +652,7 @@ iss::status riscv_hart_msu_vp::read(const address_type type, const access_ case 3: { // SFENCE:VMA upper auto tvm = state.mstatus.TVM; if (this->reg.PRIV == PRIV_S & tvm != 0) { - this->trap_state = (1 << 31) | (2 << 16); + this->reg.trap_state = (1 << 31) | (2 << 16); this->fault_data = this->reg.PC; return iss::Err; } @@ -673,7 +673,7 @@ iss::status riscv_hart_msu_vp::read(const address_type type, const access_ } return iss::Ok; } catch (trap_access &ta) { - this->trap_state = (1 << 31) | ta.id; + this->reg.trap_state = (1 << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -711,7 +711,7 @@ iss::status riscv_hart_msu_vp::write(const address_type type, const access if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) { fault_data = addr; if (access && iss::access_type::DEBUG) throw trap_access(0, addr); - this->trap_state = (1 << 31); // issue trap 0 + this->reg.trap_state = (1 << 31); // issue trap 0 return iss::Err; } try { @@ -730,12 +730,12 @@ iss::status riscv_hart_msu_vp::write(const address_type type, const access write_mem(phys_addr_t{access, space, addr}, length, data): write_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data); if (unlikely(res != iss::Ok)) { - this->trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) + this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) fault_data=addr; } return res; } catch (trap_access &ta) { - this->trap_state = (1 << 31) | ta.id; + this->reg.trap_state = (1 << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -784,7 +784,7 @@ iss::status riscv_hart_msu_vp::write(const address_type type, const access ptw.clear(); auto tvm = state.mstatus.TVM; if (this->reg.PRIV == PRIV_S & tvm != 0) { - this->trap_state = (1 << 31) | (2 << 16); + this->reg.trap_state = (1 << 31) | (2 << 16); this->fault_data = this->reg.PC; return iss::Err; } @@ -800,7 +800,7 @@ iss::status riscv_hart_msu_vp::write(const address_type type, const access } return iss::Ok; } catch (trap_access &ta) { - this->trap_state = (1 << 31) | ta.id; + this->reg.trap_state = (1 << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -846,7 +846,7 @@ template iss::status riscv_hart_msu_vp::write_reg(unsigned } template iss::status riscv_hart_msu_vp::read_cycle(unsigned addr, reg_t &val) { - auto cycle_val = this->icount + cycle_offset; + auto cycle_val = this->reg.icount + cycle_offset; if (addr == mcycle) { val = static_cast(cycle_val); } else if (addr == mcycleh) { @@ -868,7 +868,7 @@ template iss::status riscv_hart_msu_vp::write_cycle(unsign mcycle_csr = (static_cast(val)<<32) + (mcycle_csr & 0xffffffff); } } - cycle_offset = mcycle_csr-this->icount; // TODO: relying on wrap-around + cycle_offset = mcycle_csr-this->reg.icount; // TODO: relying on wrap-around return iss::Ok; } @@ -899,7 +899,7 @@ template iss::status riscv_hart_msu_vp::write_instret(unsi } template iss::status riscv_hart_msu_vp::read_time(unsigned addr, reg_t &val) { - uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052; + uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052; if (addr == time) { val = static_cast(time_val); } else if (addr == timeh) { @@ -968,7 +968,7 @@ template iss::status riscv_hart_msu_vp::write_epc(unsigned template iss::status riscv_hart_msu_vp::read_satp(unsigned addr, reg_t &val) { reg_t tvm = state.mstatus.TVM; if (this->reg.PRIV == PRIV_S & tvm != 0) { - this->trap_state = (1 << 31) | (2 << 16); + this->reg.trap_state = (1 << 31) | (2 << 16); this->fault_data = this->reg.PC; return iss::Err; } @@ -979,7 +979,7 @@ template iss::status riscv_hart_msu_vp::read_satp(unsigned template iss::status riscv_hart_msu_vp::write_satp(unsigned addr, reg_t val) { reg_t tvm = state.mstatus.TVM; if (this->reg.PRIV == PRIV_S & tvm != 0) { - this->trap_state = (1 << 31) | (2 << 16); + this->reg.trap_state = (1 << 31) | (2 << 16); this->fault_data = this->reg.PC; return iss::Err; } @@ -1024,18 +1024,6 @@ template iss::status riscv_hart_msu_vp::write_fcsr(unsigne template iss::status riscv_hart_msu_vp::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { switch (paddr.val) { - case 0x0200BFF8: { // CLINT base, mtime reg - if (sizeof(reg_t) < length) return iss::Err; - reg_t time_val; - this->read_csr(time, time_val); - std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data); - } break; - case 0x10008000: { - const mem_type::page_type &p = mem(paddr.val / mem.page_size); - uint64_t offs = paddr.val & mem.page_addr_mask; - std::copy(p.data() + offs, p.data() + offs + length, data); - if (this->icount > 30000) data[3] |= 0x80; - } break; default: { for(auto offs=0U; offs::read_mem(phys_addr_t paddr, unsigned length template iss::status riscv_hart_msu_vp::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { switch (paddr.val) { - case 0x10013000: // UART0 base, TXFIFO reg - case 0x10023000: // UART1 base, TXFIFO reg - uart_buf << (char)data[0]; + case 0xFFFF0000: // UART0 base, TXFIFO reg if (((char)data[0]) == '\n' || data[0] == 0) { - // LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send - // '"<>12)&0x3)<<" send '"<::write_mem(phys_addr_t paddr, unsigned lengt LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar << "), stopping simulation"; } - this->trap_state=std::numeric_limits::max(); + this->reg.trap_state=std::numeric_limits::max(); this->interrupt_sim=hostvar; break; //throw(iss::simulation_stopped(hostvar)); @@ -1162,7 +1133,7 @@ template void riscv_hart_msu_vp::check_interrupt() { if (enabled_interrupts != 0) { int res = 0; while ((enabled_interrupts & 1) == 0) enabled_interrupts >>= 1, res++; - this->pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id + this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id } } @@ -1306,7 +1277,7 @@ template uint64_t riscv_hart_msu_vp::enter_trap(uint64_t f if (cur_priv != PRIV_M && ((csr[mideleg] >> cause) & 0x1) != 0) new_priv = (csr[sideleg] >> cause) & 0x1 ? PRIV_U : PRIV_S; csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt - this->pending_trap = 0; + this->reg.pending_trap = 0; } size_t adr = ucause | (new_priv << 8); csr[adr] = (trap_id << 31) + cause; @@ -1351,7 +1322,7 @@ template uint64_t riscv_hart_msu_vp::enter_trap(uint64_t f << lvl[cur_priv] << " to " << lvl[new_priv]; // reset trap state this->reg.PRIV = new_priv; - this->trap_state = 0; + this->reg.trap_state = 0; update_vm_info(); return this->reg.NEXT_PC; } @@ -1363,7 +1334,7 @@ template uint64_t riscv_hart_msu_vp::leave_trap(uint64_t f auto tsr = state.mstatus.TSR; if (cur_priv == PRIV_S && inst_priv == PRIV_S && tsr != 0) { - this->trap_state = (1 << 31) | (2 << 16); + this->reg.trap_state = (1 << 31) | (2 << 16); this->fault_data = this->reg.PC; return this->reg.PC; } @@ -1402,7 +1373,7 @@ template void riscv_hart_msu_vp::wait_until(uint64_t flags auto status = state.mstatus; auto tw = status.TW; if (this->reg.PRIV == PRIV_S && tw != 0) { - this->trap_state = (1 << 31) | (2 << 16); + this->reg.trap_state = (1 << 31) | (2 << 16); this->fault_data = this->reg.PC; } } diff --git a/src/iss/arch/riscv_hart_mu_p.h b/src/iss/arch/riscv_hart_mu_p.h index 719276d..513ca20 100644 --- a/src/iss/arch/riscv_hart_mu_p.h +++ b/src/iss/arch/riscv_hart_mu_p.h @@ -304,7 +304,7 @@ public: void disass_output(uint64_t pc, const std::string instr) override { CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", - pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->icount + cycle_offset); + pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.icount + cycle_offset); }; iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; } @@ -816,7 +816,7 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc if(!pmp_check(access, addr, length) && !is_debug(access)) { fault_data = addr; if (is_debug(access)) throw trap_access(0, addr); - this->trap_state = (1UL << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1 + this->reg.trap_state = (1UL << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1 return iss::Err; } } @@ -824,12 +824,12 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { fault_data = addr; if (is_debug(access)) throw trap_access(0, addr); - this->trap_state = (1UL << 31); // issue trap 0 + this->reg.trap_state = (1UL << 31); // issue trap 0 return iss::Err; } try { if(!is_debug(access) && (addr&(alignment-1))){ - this->trap_state = (1UL << 31) | 4<<16; + this->reg.trap_state = (1UL << 31) | 4<<16; fault_data=addr; return iss::Err; } @@ -848,12 +848,12 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc res = hart_mem_rd_delegate( phys_addr, length, data); } if (unlikely(res != iss::Ok)){ - this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault + this->reg.trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault fault_data=addr; } return res; } catch (trap_access &ta) { - this->trap_state = (1UL << 31) | ta.id; + this->reg.trap_state = (1UL << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -879,7 +879,7 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc } return iss::Ok; } catch (trap_access &ta) { - this->trap_state = (1UL << 31) | ta.id; + this->reg.trap_state = (1UL << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -918,19 +918,19 @@ iss::status riscv_hart_mu_p::write(const address_type type, const ac if(!pmp_check(access, addr, length) && (access&access_type::DEBUG) != access_type::DEBUG) { fault_data = addr; if (access && iss::access_type::DEBUG) throw trap_access(0, addr); - this->trap_state = (1UL << 31) | (7 << 16); // issue trap 1 + this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 1 return iss::Err; } } if (unlikely(is_fetch(access) && (addr & 0x1) == 1)) { fault_data = addr; if (access && iss::access_type::DEBUG) throw trap_access(0, addr); - this->trap_state = (1UL << 31); // issue trap 0 + this->reg.trap_state = (1UL << 31); // issue trap 0 return iss::Err; } try { if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){ - this->trap_state = (1UL << 31) | 6<<16; + this->reg.trap_state = (1UL << 31) | 6<<16; fault_data=addr; return iss::Err; } @@ -949,12 +949,12 @@ iss::status riscv_hart_mu_p::write(const address_type type, const ac res = hart_mem_wr_delegate( phys_addr, length, data); } if (unlikely(res != iss::Ok)) { - this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) + this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) fault_data=addr; } return res; } catch (trap_access &ta) { - this->trap_state = (1UL << 31) | ta.id; + this->reg.trap_state = (1UL << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -1014,7 +1014,7 @@ iss::status riscv_hart_mu_p::write(const address_type type, const ac } return iss::Ok; } catch (trap_access &ta) { - this->trap_state = (1UL << 31) | ta.id; + this->reg.trap_state = (1UL << 31) | ta.id; fault_data=ta.addr; return iss::Err; } @@ -1060,7 +1060,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_cycle(unsigned addr, reg_t &val) { - auto cycle_val = this->icount + cycle_offset; + auto cycle_val = this->reg.icount + cycle_offset; if (addr == mcycle) { val = static_cast(cycle_val); } else if (addr == mcycleh) { @@ -1079,35 +1079,35 @@ template iss::status riscv_hart_mu_p(val)<<32) + (mcycle_csr & 0xffffffff); } } - cycle_offset = mcycle_csr-this->icount; // TODO: relying on wrap-around + cycle_offset = mcycle_csr-this->reg.icount; // TODO: relying on wrap-around return iss::Ok; } template iss::status riscv_hart_mu_p::read_instret(unsigned addr, reg_t &val) { if ((addr&0xff) == (minstret&0xff)) { - val = static_cast(this->instret); + val = static_cast(this->reg.instret); } else if ((addr&0xff) == (minstreth&0xff)) { - val = static_cast(this->instret >> 32); + val = static_cast(this->reg.instret >> 32); } return iss::Ok; } template iss::status riscv_hart_mu_p::write_instret(unsigned addr, reg_t val) { if (sizeof(typename traits::reg_t) != 4) { - this->instret = static_cast(val); + this->reg.instret = static_cast(val); } else { if ((addr&0xff) == (minstret&0xff)) { - this->instret = (this->instret & 0xffffffff00000000) + val; + this->reg.instret = (this->reg.instret & 0xffffffff00000000) + val; } else { - this->instret = (static_cast(val)<<32) + (this->instret & 0xffffffff); + this->reg.instret = (static_cast(val)<<32) + (this->reg.instret & 0xffffffff); } } - this->instret--; + this->reg.instret--; return iss::Ok; } template iss::status riscv_hart_mu_p::read_time(unsigned addr, reg_t &val) { - uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052; + uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052; if (addr == time) { val = static_cast(time_val); } else if (addr == timeh) { @@ -1283,18 +1283,6 @@ iss::status riscv_hart_mu_p::write_xtvt(unsigned addr, reg_t val) { template iss::status riscv_hart_mu_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { switch (paddr.val) { - case 0x0200BFF8: { // CLINT base, mtime reg - if (sizeof(reg_t) < length) return iss::Err; - reg_t time_val; - this->read_csr(time, time_val); - std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data); - } break; - case 0x10008000: { - const mem_type::page_type &p = mem(paddr.val / mem.page_size); - uint64_t offs = paddr.val & mem.page_addr_mask; - std::copy(p.data() + offs, p.data() + offs + length, data); - if (this->icount > 30000) data[3] |= 0x80; - } break; default: { for(auto offs=0U; offs::read_mem(phys_addr_t paddr, unsigned le template iss::status riscv_hart_mu_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { switch (paddr.val) { - case 0x10013000: // UART0 base, TXFIFO reg - case 0x10023000: // UART1 base, TXFIFO reg - uart_buf << (char)data[0]; + case 0xFFFF0000: // UART0 base, TXFIFO reg if (((char)data[0]) == '\n' || data[0] == 0) { - LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send '"<>12)&0x3)<<" send '"<::write_mem(phys_addr_t paddr, unsigned l LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar << "), stopping simulation"; } - this->trap_state=std::numeric_limits::max(); + this->reg.trap_state=std::numeric_limits::max(); this->interrupt_sim=hostvar; break; //throw(iss::simulation_stopped(hostvar)); @@ -1436,14 +1408,14 @@ template void riscv_hart_mu_p::chec enabled_interrupts >>= 1; res++; } - this->pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id + this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id } } template uint64_t riscv_hart_mu_p::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) { // flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0] // calculate and write mcause val - if(flags==std::numeric_limits::max()) flags=this->trap_state; + if(flags==std::numeric_limits::max()) flags=this->reg.trap_state; auto trap_id = bit_sub<0, 16>(flags); auto cause = bit_sub<16, 15>(flags); if (trap_id == 0 && cause == 11) cause = 0x8 + this->reg.PRIV; // adjust environment call cause @@ -1490,7 +1462,7 @@ template uint64_t riscv_hart_mu_p:: if (this->reg.PRIV != PRIV_M && ((csr[mideleg] >> cause) & 0x1) != 0) new_priv = PRIV_U; csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt - this->pending_trap = 0; + this->reg.pending_trap = 0; } size_t adr = ucause | (new_priv << 8); csr[adr] = (trap_id << (traits::XLEN-1)) + cause; @@ -1543,7 +1515,7 @@ template uint64_t riscv_hart_mu_p:: << lvl[this->reg.PRIV] << " to " << lvl[new_priv]; // reset trap state this->reg.PRIV = new_priv; - this->trap_state = 0; + this->reg.trap_state = 0; return this->reg.NEXT_PC; } @@ -1552,7 +1524,7 @@ template uint64_t riscv_hart_mu_p:: auto inst_priv = (flags & 0x3)? 3:0; if(inst_priv>cur_priv){ auto trap_val = 0x80ULL << 24 | (2 << 16); // illegal instruction - this->trap_state = trap_val; + this->reg.trap_state = trap_val; this->reg.NEXT_PC = std::numeric_limits::max(); } else { auto status = state.mstatus; diff --git a/src/iss/arch/tgc_c.cpp b/src/iss/arch/tgc_c.cpp index ed4d7ca..e4fc905 100644 --- a/src/iss/arch/tgc_c.cpp +++ b/src/iss/arch/tgc_c.cpp @@ -55,8 +55,8 @@ void tgc_c::reset(uint64_t address) { reg.PC=address; reg.NEXT_PC=reg.PC; reg.PRIV=0x3; - trap_state=0; - icount=0; + reg.trap_state=0; + reg.icount=0; } uint8_t *tgc_c::get_regs_base_ptr() { diff --git a/src/iss/arch/tgc_c.h b/src/iss/arch/tgc_c.h index 53776c0..4d47835 100644 --- a/src/iss/arch/tgc_c.h +++ b/src/iss/arch/tgc_c.h @@ -189,7 +189,7 @@ struct tgc_c: public arch_if { uint8_t* get_regs_base_ptr() override; - inline uint64_t get_icount() { return icount; } + inline uint64_t get_icount() { return reg.icount; } inline bool should_stop() { return interrupt_sim; } @@ -207,7 +207,7 @@ struct tgc_c: public arch_if { virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } - inline uint32_t get_last_branch() { return last_branch; } + inline uint32_t get_last_branch() { return reg.last_branch; } #pragma pack(push, 1) @@ -256,12 +256,6 @@ struct tgc_c: public arch_if { uint32_t last_branch = 0; } reg; #pragma pack(pop) - uint32_t trap_state = 0, pending_trap = 0; - uint64_t icount = 0; - uint64_t cycle = 0; - uint64_t instret = 0; - uint32_t instruction = 0; - uint32_t last_branch = 0; std::array addr_mode; uint64_t interrupt_sim=0; diff --git a/src/main.cpp b/src/main.cpp index 2cd1316..e2b7850 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -71,7 +71,7 @@ int main(int argc, char *argv[]) { ("elf,f", po::value>(), "ELF file(s) to load") ("mem,m", po::value(), "the memory input file") ("plugin,p", po::value>(), "plugin to activate") - ("backend", po::value()->default_value("interp"), "the memory input file") + ("backend", po::value()->default_value("interp"), "the ISS backend to use, options are: interp, tcc") ("isa", po::value()->default_value("tgc_c"), "isa to use for simulation"); // clang-format on auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 3e54a25..e59d80d 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -115,7 +115,7 @@ protected: inline void raise(uint16_t trap_id, uint16_t cause){ auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id; - this->core.trap_state = trap_val; + this->core.reg.trap_state = trap_val; this->template get_reg(traits::NEXT_PC) = std::numeric_limits::max(); } @@ -322,16 +322,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto pc=start; auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); - auto& trap_state = this->core.trap_state; - auto& icount = this->core.icount; - auto& cycle = this->core.cycle; - auto& instret = this->core.instret; - auto& instr = this->core.instruction; + auto& trap_state = this->core.reg.trap_state; + auto& icount = this->core.reg.icount; + auto& cycle = this->core.reg.cycle; + auto& instret = this->core.reg.instret; + auto& instr = this->core.reg.instruction; // we fetch at max 4 byte, alignment is 2 auto *const data = reinterpret_cast(&instr); while(!this->core.should_stop() && - !(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){ + !(is_count_limit_enabled(cond) && icount >= icount_limit)){ if(fetch_ins(pc, data)!=iss::Ok){ this->do_sync(POST_SYNC, std::numeric_limits::max()); pc.val = super::core.enter_trap(std::numeric_limits::max(), pc.val, 0); @@ -340,7 +340,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co (instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0' auto inst_id = decode_inst_id(instr); // pre execution stuff - this->core.last_branch = 0; + this->core.reg.last_branch = 0; if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast(inst_id)); switch(inst_id){ case arch::traits::opcode_e::LUI: { @@ -422,7 +422,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *(X+rd) = *PC + 4; } *NEXT_PC = *PC + (int32_t)sext<21>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } } @@ -457,7 +457,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *(X+rd) = *PC + 4; } *NEXT_PC = new_pc & ~ 0x1; - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } } @@ -489,7 +489,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { *NEXT_PC = *PC + (int16_t)sext<13>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } } @@ -522,7 +522,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { *NEXT_PC = *PC + (int16_t)sext<13>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } } @@ -555,7 +555,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { *NEXT_PC = *PC + (int16_t)sext<13>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } } @@ -588,7 +588,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { *NEXT_PC = *PC + (int16_t)sext<13>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } } @@ -621,7 +621,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { *NEXT_PC = *PC + (int16_t)sext<13>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } } @@ -654,7 +654,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { *NEXT_PC = *PC + (int16_t)sext<13>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } } @@ -683,7 +683,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); int8_t read_res = super::template read_mem(traits::MEM, load_address); - if(this->core.trap_state>=0x80000000UL) goto TRAP_LB; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LB; int8_t res = (int8_t)read_res; if(rd != 0) { *(X+rd) = (uint32_t)res; @@ -714,7 +714,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); int16_t read_res = super::template read_mem(traits::MEM, load_address); - if(this->core.trap_state>=0x80000000UL) goto TRAP_LH; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LH; int16_t res = (int16_t)read_res; if(rd != 0) { *(X+rd) = (uint32_t)res; @@ -745,7 +745,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); int32_t read_res = super::template read_mem(traits::MEM, load_address); - if(this->core.trap_state>=0x80000000UL) goto TRAP_LW; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LW; int32_t res = (int32_t)read_res; if(rd != 0) { *(X+rd) = (uint32_t)res; @@ -776,7 +776,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); uint8_t read_res = super::template read_mem(traits::MEM, load_address); - if(this->core.trap_state>=0x80000000UL) goto TRAP_LBU; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LBU; uint8_t res = (uint8_t)read_res; if(rd != 0) { *(X+rd) = (uint32_t)res; @@ -807,7 +807,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm); uint16_t read_res = super::template read_mem(traits::MEM, load_address); - if(this->core.trap_state>=0x80000000UL) goto TRAP_LHU; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LHU; uint16_t res = (uint16_t)read_res; if(rd != 0) { *(X+rd) = (uint32_t)res; @@ -838,7 +838,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); super::template write_mem(traits::MEM, store_address, (int8_t)*(X+rs2)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_SB; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SB; } } TRAP_SB:break; @@ -865,7 +865,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); super::template write_mem(traits::MEM, store_address, (int16_t)*(X+rs2)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_SH; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SH; } } TRAP_SH:break; @@ -892,7 +892,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm); super::template write_mem(traits::MEM, store_address, (int32_t)*(X+rs2)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_SW; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SW; } } TRAP_SW:break; @@ -1428,7 +1428,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction { super::template write_mem(traits::FENCE, traits::fence, pred << 4 | succ); - if(this->core.trap_state>=0x80000000UL) goto TRAP_FENCE; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_FENCE; } TRAP_FENCE:break; }// @suppress("No break at end of case") @@ -1507,15 +1507,15 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co uint32_t xrs1 = *(X+rs1); if(rd != 0) { uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW; uint32_t xrd = read_res; super::template write_mem(traits::CSR, csr, xrs1); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW; *(X+rd) = xrd; } else { super::template write_mem(traits::CSR, csr, xrs1); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW; } } } @@ -1542,12 +1542,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRS; uint32_t xrd = read_res; uint32_t xrs1 = *(X+rs1); if(rs1 != 0) { super::template write_mem(traits::CSR, csr, xrd | xrs1); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRS; } if(rd != 0) { *(X+rd) = xrd; @@ -1577,12 +1577,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRC; uint32_t xrd = read_res; uint32_t xrs1 = *(X+rs1); if(rs1 != 0) { super::template write_mem(traits::CSR, csr, xrd & ~ xrs1); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRC; } if(rd != 0) { *(X+rd) = xrd; @@ -1612,10 +1612,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRWI; uint32_t xrd = read_res; super::template write_mem(traits::CSR, csr, (uint32_t)zimm); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRWI; if(rd != 0) { *(X+rd) = xrd; } @@ -1644,11 +1644,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRSI; uint32_t xrd = read_res; if(zimm != 0) { super::template write_mem(traits::CSR, csr, xrd | (uint32_t)zimm); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRSI; } if(rd != 0) { *(X+rd) = xrd; @@ -1678,11 +1678,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRCI; uint32_t xrd = read_res; if(zimm != 0) { super::template write_mem(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRCI; } if(rd != 0) { *(X+rd) = xrd; @@ -1707,7 +1707,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction { super::template write_mem(traits::FENCE, traits::fencei, imm); - if(this->core.trap_state>=0x80000000UL) goto TRAP_FENCE_I; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_FENCE_I; } TRAP_FENCE_I:break; }// @suppress("No break at end of case") @@ -2015,7 +2015,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t load_address = *(X+rs1 + 8) + uimm; int32_t read_res = super::template read_mem(traits::MEM, load_address); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CLW; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLW; *(X+rd + 8) = (int32_t)read_res; } TRAP_CLW:break; @@ -2038,7 +2038,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { uint32_t load_address = *(X+rs1 + 8) + uimm; super::template write_mem(traits::MEM, load_address, (int32_t)*(X+rs2 + 8)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSW; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSW; } TRAP_CSW:break; }// @suppress("No break at end of case") @@ -2097,7 +2097,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { *(X+1) = *PC + 2; *NEXT_PC = *PC + (int16_t)sext<12>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } TRAP_CJAL:break; }// @suppress("No break at end of case") @@ -2342,7 +2342,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // execute instruction { *NEXT_PC = *PC + (int16_t)sext<12>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } TRAP_CJ:break; }// @suppress("No break at end of case") @@ -2363,7 +2363,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { if(*(X+rs1 + 8) == 0) { *NEXT_PC = *PC + (int16_t)sext<9>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } TRAP_CBEQZ:break; @@ -2385,7 +2385,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { if(*(X+rs1 + 8) != 0) { *NEXT_PC = *PC + (int16_t)sext<9>(imm); - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } TRAP_CBNEZ:break; @@ -2436,7 +2436,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co } else { int32_t read_res = super::template read_mem(traits::MEM, *(X+2) + uimm); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CLWSP; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLWSP; int32_t res = read_res; *(X+rd) = (int32_t)res; } @@ -2485,7 +2485,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co { if(rs1 && rs1 < traits::RFS) { *NEXT_PC = *(X+rs1 % traits::RFS) & ~ 0x1; - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } else { raise(0, 2); @@ -2553,7 +2553,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co uint32_t new_pc = *(X+rs1); *(X+1) = *PC + 2; *NEXT_PC = new_pc & ~ 0x1; - this->core.last_branch = 1; + this->core.reg.last_branch = 1; } } TRAP_CJALR:break; @@ -2592,7 +2592,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co else { uint32_t offs = *(X+2) + uimm; super::template write_mem(traits::MEM, offs, (uint32_t)*(X+rs2)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSWSP; + if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSWSP; } } TRAP_CSWSP:break; @@ -2618,8 +2618,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // post execution stuff process_spawn_blocks(); if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast(inst_id)); - // if(!this->core.trap_state) // update trap state if there is a pending interrupt - // this->core.trap_state = this->core.pending_trap; + // if(!this->core.reg.trap_state) // update trap state if there is a pending interrupt + // this->core.reg.trap_state = this->core.reg.pending_trap; // trap check if(trap_state!=0){ super::core.enter_trap(trap_state, pc.val, instr); @@ -2630,7 +2630,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co cycle++; pc.val=*NEXT_PC; this->core.reg.PC = this->core.reg.NEXT_PC; - this->core.trap_state = this->core.pending_trap; + this->core.reg.trap_state = this->core.reg.pending_trap; } } return pc; diff --git a/src/vm/tcc/vm_tgc_c.cpp b/src/vm/tcc/vm_tgc_c.cpp index bd988a0..f68372f 100644 --- a/src/vm/tcc/vm_tgc_c.cpp +++ b/src/vm/tcc/vm_tgc_c.cpp @@ -384,6 +384,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -393,9 +394,8 @@ private: tu.store(rd + traits::X0,tu.constant((uint32_t)((int32_t)imm),32)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,0); gen_trap_check(tu); return returnValue; @@ -416,6 +416,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -425,9 +426,8 @@ private: tu.store(rd + traits::X0,tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int32_t)imm,32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,1); gen_trap_check(tu); return returnValue; @@ -448,6 +448,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -461,12 +462,11 @@ private: } auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int32_t)sext<21>(imm),32)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,2); gen_trap_check(tu); return returnValue; @@ -488,6 +488,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -502,12 +503,11 @@ private: } auto PC_val_v = tu.assignment("PC_val", tu.bitwise_and(new_pc,tu.constant(~ 0x1,8)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); tu.close_scope(); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,3); gen_trap_check(tu); return returnValue; @@ -529,6 +529,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -540,13 +541,12 @@ private: else{ auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<13>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } tu.close_scope(); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,4); gen_trap_check(tu); return returnValue; @@ -568,6 +568,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -579,13 +580,12 @@ private: else{ auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<13>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } tu.close_scope(); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,5); gen_trap_check(tu); return returnValue; @@ -607,6 +607,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -618,13 +619,12 @@ private: else{ auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<13>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } tu.close_scope(); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,6); gen_trap_check(tu); return returnValue; @@ -646,6 +646,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -657,13 +658,12 @@ private: else{ auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<13>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } tu.close_scope(); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,7); gen_trap_check(tu); return returnValue; @@ -685,6 +685,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -696,13 +697,12 @@ private: else{ auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<13>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } tu.close_scope(); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,8); gen_trap_check(tu); return returnValue; @@ -724,6 +724,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -735,13 +736,12 @@ private: else{ auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<13>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } tu.close_scope(); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,9); gen_trap_check(tu); return returnValue; @@ -763,6 +763,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -774,9 +775,8 @@ private: tu.store(rd + traits::X0,tu.ext(res,32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,10); gen_trap_check(tu); return returnValue; @@ -798,6 +798,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -809,9 +810,8 @@ private: tu.store(rd + traits::X0,tu.ext(res,32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,11); gen_trap_check(tu); return returnValue; @@ -833,6 +833,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -844,9 +845,8 @@ private: tu.store(rd + traits::X0,tu.ext(res,32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,12); gen_trap_check(tu); return returnValue; @@ -868,6 +868,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -879,9 +880,8 @@ private: tu.store(rd + traits::X0,tu.ext(res,32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,13); gen_trap_check(tu); return returnValue; @@ -903,6 +903,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -914,9 +915,8 @@ private: tu.store(rd + traits::X0,tu.ext(res,32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,14); gen_trap_check(tu); return returnValue; @@ -938,6 +938,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -946,9 +947,8 @@ private: auto store_address = tu.assignment(tu.add(tu.load(rs1+ traits::X0, 0),tu.constant((int16_t)sext<12>(imm),16)),32); tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),8,false)); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,15); gen_trap_check(tu); return returnValue; @@ -970,6 +970,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -978,9 +979,8 @@ private: auto store_address = tu.assignment(tu.add(tu.load(rs1+ traits::X0, 0),tu.constant((int16_t)sext<12>(imm),16)),32); tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),16,false)); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,16); gen_trap_check(tu); return returnValue; @@ -1002,6 +1002,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1010,9 +1011,8 @@ private: auto store_address = tu.assignment(tu.add(tu.load(rs1+ traits::X0, 0),tu.constant((int16_t)sext<12>(imm),16)),32); tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),32,false)); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,17); gen_trap_check(tu); return returnValue; @@ -1034,6 +1034,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1043,9 +1044,8 @@ private: tu.store(rd + traits::X0,tu.add(tu.load(rs1+ traits::X0, 0),tu.constant((int16_t)sext<12>(imm),16))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,18); gen_trap_check(tu); return returnValue; @@ -1067,6 +1067,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1076,9 +1077,8 @@ private: tu.store(rd + traits::X0,tu.conditionalAssignment((tu.icmp(ICmpInst::ICMP_SLT,tu.ext(tu.load(rs1+ traits::X0, 0),32,true),tu.constant((int16_t)sext<12>(imm),16))), tu.constant( 1,32),tu.constant( 0,32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,19); gen_trap_check(tu); return returnValue; @@ -1100,6 +1100,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1109,9 +1110,8 @@ private: tu.store(rd + traits::X0,tu.conditionalAssignment((tu.icmp(ICmpInst::ICMP_SLT,tu.load(rs1+ traits::X0, 0),tu.constant((uint32_t)((int16_t)sext<12>(imm)),32))), tu.constant( 1,32),tu.constant( 0,32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,20); gen_trap_check(tu); return returnValue; @@ -1133,6 +1133,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1142,9 +1143,8 @@ private: tu.store(rd + traits::X0,tu.bitwise_xor(tu.load(rs1+ traits::X0, 0),tu.constant((uint32_t)((int16_t)sext<12>(imm)),32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,21); gen_trap_check(tu); return returnValue; @@ -1166,6 +1166,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1175,9 +1176,8 @@ private: tu.store(rd + traits::X0,tu.bitwise_or(tu.load(rs1+ traits::X0, 0),tu.constant((uint32_t)((int16_t)sext<12>(imm)),32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,22); gen_trap_check(tu); return returnValue; @@ -1199,6 +1199,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1208,9 +1209,8 @@ private: tu.store(rd + traits::X0,tu.bitwise_and(tu.load(rs1+ traits::X0, 0),tu.constant((uint32_t)((int16_t)sext<12>(imm)),32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,23); gen_trap_check(tu); return returnValue; @@ -1232,6 +1232,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1241,9 +1242,8 @@ private: tu.store(rd + traits::X0,tu.shl(tu.load(rs1+ traits::X0, 0),tu.constant(shamt,8))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,24); gen_trap_check(tu); return returnValue; @@ -1265,6 +1265,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1274,9 +1275,8 @@ private: tu.store(rd + traits::X0,tu.lshr(tu.load(rs1+ traits::X0, 0),tu.constant(shamt,8))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,25); gen_trap_check(tu); return returnValue; @@ -1298,6 +1298,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1307,9 +1308,8 @@ private: tu.store(rd + traits::X0,tu.lshr(tu.ext(tu.load(rs1+ traits::X0, 0),32,true),tu.constant(shamt,8))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,26); gen_trap_check(tu); return returnValue; @@ -1331,6 +1331,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1340,9 +1341,8 @@ private: tu.store(rd + traits::X0,tu.add(tu.load(rs1+ traits::X0, 0),tu.load(rs2+ traits::X0, 0))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,27); gen_trap_check(tu); return returnValue; @@ -1364,6 +1364,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1373,9 +1374,8 @@ private: tu.store(rd + traits::X0,tu.sub(tu.load(rs1+ traits::X0, 0),tu.load(rs2+ traits::X0, 0))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,28); gen_trap_check(tu); return returnValue; @@ -1397,6 +1397,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1406,9 +1407,8 @@ private: tu.store(rd + traits::X0,tu.shl(tu.load(rs1+ traits::X0, 0),(tu.bitwise_and(tu.load(rs2+ traits::X0, 0),tu.constant((static_cast(traits:: XLEN)- 1),64))))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,29); gen_trap_check(tu); return returnValue; @@ -1430,6 +1430,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1439,9 +1440,8 @@ private: tu.store(rd + traits::X0,tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_SLT,tu.ext(tu.load(rs1+ traits::X0, 0),32,true),tu.ext(tu.load(rs2+ traits::X0, 0),32,true)), tu.constant( 1,32),tu.constant( 0,32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,30); gen_trap_check(tu); return returnValue; @@ -1463,6 +1463,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1472,9 +1473,8 @@ private: tu.store(rd + traits::X0,tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_SLT,tu.load(rs1+ traits::X0, 0),tu.load(rs2+ traits::X0, 0)), tu.constant( 1,32),tu.constant( 0,32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,31); gen_trap_check(tu); return returnValue; @@ -1496,6 +1496,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1505,9 +1506,8 @@ private: tu.store(rd + traits::X0,tu.bitwise_xor(tu.load(rs1+ traits::X0, 0),tu.load(rs2+ traits::X0, 0))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,32); gen_trap_check(tu); return returnValue; @@ -1529,6 +1529,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1538,9 +1539,8 @@ private: tu.store(rd + traits::X0,tu.lshr(tu.load(rs1+ traits::X0, 0),(tu.bitwise_and(tu.load(rs2+ traits::X0, 0),tu.constant((static_cast(traits:: XLEN)- 1),64))))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,33); gen_trap_check(tu); return returnValue; @@ -1562,6 +1562,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1571,9 +1572,8 @@ private: tu.store(rd + traits::X0,tu.lshr(tu.ext(tu.load(rs1+ traits::X0, 0),32,true),(tu.bitwise_and(tu.load(rs2+ traits::X0, 0),tu.constant((static_cast(traits:: XLEN)- 1),64))))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,34); gen_trap_check(tu); return returnValue; @@ -1595,6 +1595,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1604,9 +1605,8 @@ private: tu.store(rd + traits::X0,tu.bitwise_or(tu.load(rs1+ traits::X0, 0),tu.load(rs2+ traits::X0, 0))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,35); gen_trap_check(tu); return returnValue; @@ -1628,6 +1628,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1637,9 +1638,8 @@ private: tu.store(rd + traits::X0,tu.bitwise_and(tu.load(rs1+ traits::X0, 0),tu.load(rs2+ traits::X0, 0))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,36); gen_trap_check(tu); return returnValue; @@ -1663,11 +1663,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.write_mem(traits::MEM, static_cast(traits:: fence), tu.constant(pred<< 4|succ,8)); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,37); gen_trap_check(tu); return returnValue; @@ -1683,10 +1683,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); this->gen_raise_trap(tu, 0, 11); + auto returnValue = std::make_tuple(CONT); tu.close_scope(); - auto returnValue = std::make_tuple(BRANCH); vm_base::gen_sync(tu, POST_SYNC,38); gen_trap_check(tu); return returnValue; @@ -1702,10 +1703,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); this->gen_raise_trap(tu, 0, 3); + auto returnValue = std::make_tuple(CONT); tu.close_scope(); - auto returnValue = std::make_tuple(BRANCH); vm_base::gen_sync(tu, POST_SYNC,39); gen_trap_check(tu); return returnValue; @@ -1721,10 +1723,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); this->gen_leave_trap(tu, 3); + auto returnValue = std::make_tuple(CONT); tu.close_scope(); - auto returnValue = std::make_tuple(BRANCH); vm_base::gen_sync(tu, POST_SYNC,40); gen_trap_check(tu); return returnValue; @@ -1740,11 +1743,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); this->gen_wait(tu, 1); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,41); gen_trap_check(tu); return returnValue; @@ -1766,6 +1769,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1780,9 +1784,8 @@ private: tu.write_mem(traits::MEM, csr, xrs1); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,42); gen_trap_check(tu); return returnValue; @@ -1804,6 +1807,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1818,9 +1822,8 @@ private: tu.store(rd + traits::X0,xrd); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,43); gen_trap_check(tu); return returnValue; @@ -1842,6 +1845,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1856,9 +1860,8 @@ private: tu.store(rd + traits::X0,xrd); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,44); gen_trap_check(tu); return returnValue; @@ -1880,6 +1883,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1891,9 +1895,8 @@ private: tu.store(rd + traits::X0,xrd); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,45); gen_trap_check(tu); return returnValue; @@ -1915,6 +1918,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1928,9 +1932,8 @@ private: tu.store(rd + traits::X0,xrd); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,46); gen_trap_check(tu); return returnValue; @@ -1952,6 +1955,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -1965,9 +1969,8 @@ private: tu.store(rd + traits::X0,xrd); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,47); gen_trap_check(tu); return returnValue; @@ -1989,11 +1992,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.write_mem(traits::MEM, static_cast(traits:: fencei), tu.constant(imm,16)); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,48); gen_trap_check(tu); return returnValue; @@ -2015,6 +2018,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2025,9 +2029,8 @@ private: tu.store(rd + traits::X0,tu.ext(res,32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,49); gen_trap_check(tu); return returnValue; @@ -2049,6 +2052,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2059,9 +2063,8 @@ private: tu.store(rd + traits::X0,tu.ext((tu.lshr(res,tu.constant(static_cast(traits:: XLEN),32))),32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,50); gen_trap_check(tu); return returnValue; @@ -2083,6 +2086,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2093,9 +2097,8 @@ private: tu.store(rd + traits::X0,tu.ext((tu.lshr(res,tu.constant(static_cast(traits:: XLEN),32))),32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,51); gen_trap_check(tu); return returnValue; @@ -2117,6 +2120,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2127,9 +2131,8 @@ private: tu.store(rd + traits::X0,tu.ext((tu.lshr(res,tu.constant(static_cast(traits:: XLEN),32))),32,true)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,52); gen_trap_check(tu); return returnValue; @@ -2151,6 +2154,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2170,9 +2174,8 @@ private: tu.close_scope(); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,53); gen_trap_check(tu); return returnValue; @@ -2194,6 +2197,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2209,9 +2213,8 @@ private: } tu.close_scope(); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,54); gen_trap_check(tu); return returnValue; @@ -2233,6 +2236,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2255,9 +2259,8 @@ private: } tu.close_scope(); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,55); gen_trap_check(tu); return returnValue; @@ -2279,6 +2282,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rs1>=static_cast(traits:: RFS)||rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2294,9 +2298,8 @@ private: } tu.close_scope(); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,56); gen_trap_check(tu); return returnValue; @@ -2317,6 +2320,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(imm) { tu.store(rd+ 8 + traits::X0,tu.add(tu.load(2+ traits::X0, 0),tu.constant(imm,8))); @@ -2324,9 +2328,8 @@ private: else{ this->gen_raise_trap(tu, 0, 2); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,57); gen_trap_check(tu); return returnValue; @@ -2348,12 +2351,12 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); auto load_address = tu.assignment(tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8)),32); tu.store(rd+ 8 + traits::X0,tu.ext(tu.read_mem(traits::MEM, load_address, 32),32,false)); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,58); gen_trap_check(tu); return returnValue; @@ -2375,12 +2378,12 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); auto load_address = tu.assignment(tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8)),32); tu.write_mem(traits::MEM, load_address, tu.ext(tu.load(rs2+ 8+ traits::X0, 0),32,false)); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,59); gen_trap_check(tu); return returnValue; @@ -2401,6 +2404,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2410,9 +2414,8 @@ private: tu.store(rs1 + traits::X0,tu.add(tu.load(rs1+ traits::X0, 0),tu.constant((int8_t)sext<6>(imm),8))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,60); gen_trap_check(tu); return returnValue; @@ -2429,10 +2432,10 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; - tu.open_scope(); - tu.close_scope(); gen_set_pc(tu, pc, traits::NEXT_PC); + tu.open_scope(); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,61); gen_trap_check(tu); return returnValue; @@ -2452,14 +2455,14 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.store(1 + traits::X0,tu.add(tu.ext(cur_pc_val,32,false),tu.constant( 2,32))); auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<12>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); - tu.close_scope(); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,62); gen_trap_check(tu); return returnValue; @@ -2480,6 +2483,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2489,9 +2493,8 @@ private: tu.store(rd + traits::X0,tu.constant((int8_t)sext<6>(imm),8)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,63); gen_trap_check(tu); return returnValue; @@ -2512,6 +2515,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(imm== 0||rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2519,9 +2523,8 @@ private: if(rd!= 0) { tu.store(rd + traits::X0,tu.constant((int32_t)sext<18>(imm),32)); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,64); gen_trap_check(tu); return returnValue; @@ -2541,6 +2544,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(nzimm) { tu.store(2 + traits::X0,tu.add(tu.load(2+ traits::X0, 0),tu.constant((int16_t)sext<10>(nzimm),16))); @@ -2548,9 +2552,8 @@ private: else{ this->gen_raise_trap(tu, 0, 2); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,65); gen_trap_check(tu); return returnValue; @@ -2567,11 +2570,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); this->gen_raise_trap(tu, 0, 2); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,66); gen_trap_check(tu); return returnValue; @@ -2592,11 +2595,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.store(rs1+ 8 + traits::X0,tu.lshr(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(shamt,8))); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,67); gen_trap_check(tu); return returnValue; @@ -2617,6 +2620,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(shamt){ tu.store(rs1+ 8 + traits::X0,tu.lshr((tu.ext(tu.load(rs1+ 8+ traits::X0, 0),32,false)),tu.constant(shamt,8))); } @@ -2624,9 +2628,8 @@ private: if(static_cast(traits:: XLEN)== 128){ tu.store(rs1+ 8 + traits::X0,tu.lshr((tu.ext(tu.load(rs1+ 8+ traits::X0, 0),32,false)),tu.constant( 64,32))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,68); gen_trap_check(tu); return returnValue; @@ -2647,11 +2650,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.store(rs1+ 8 + traits::X0,tu.bitwise_and(tu.load(rs1+ 8+ traits::X0, 0),tu.constant((int8_t)sext<6>(imm),8))); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,69); gen_trap_check(tu); return returnValue; @@ -2672,11 +2675,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.store(rd+ 8 + traits::X0,tu.sub(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0))); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,70); gen_trap_check(tu); return returnValue; @@ -2697,11 +2700,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.store(rd+ 8 + traits::X0,tu.bitwise_xor(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0))); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,71); gen_trap_check(tu); return returnValue; @@ -2722,11 +2725,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.store(rd+ 8 + traits::X0,tu.bitwise_or(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0))); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,72); gen_trap_check(tu); return returnValue; @@ -2747,11 +2750,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.store(rd+ 8 + traits::X0,tu.bitwise_and(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0))); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,73); gen_trap_check(tu); return returnValue; @@ -2771,13 +2774,13 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<12>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); - tu.close_scope(); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,74); gen_trap_check(tu); return returnValue; @@ -2798,15 +2801,15 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.open_if(tu.icmp(ICmpInst::ICMP_EQ,tu.load(rs1+ 8+ traits::X0, 0),tu.constant( 0,32))); auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<9>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); - tu.close_scope(); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,75); gen_trap_check(tu); return returnValue; @@ -2827,15 +2830,15 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); tu.open_if(tu.icmp(ICmpInst::ICMP_NE,tu.load(rs1+ 8+ traits::X0, 0),tu.constant( 0,32))); auto PC_val_v = tu.assignment("PC_val", tu.add(tu.ext(cur_pc_val,32,false),tu.constant((int16_t)sext<9>(imm),16)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); - tu.close_scope(); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,76); gen_trap_check(tu); return returnValue; @@ -2856,6 +2859,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2865,9 +2869,8 @@ private: tu.store(rs1 + traits::X0,tu.shl(tu.load(rs1+ traits::X0, 0),tu.constant(nzuimm,8))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,77); gen_trap_check(tu); return returnValue; @@ -2888,6 +2891,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)||rd== 0) { this->gen_raise_trap(tu, 0, 2); @@ -2896,9 +2900,8 @@ private: auto res = tu.assignment(tu.read_mem(traits::MEM, tu.add(tu.load(2+ traits::X0, 0),tu.constant(uimm,8)), 32),32); tu.store(rd + traits::X0,tu.ext(res,32,false)); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,78); gen_trap_check(tu); return returnValue; @@ -2919,6 +2922,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -2928,9 +2932,8 @@ private: tu.store(rd + traits::X0,tu.load(rs2+ traits::X0, 0)); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,79); gen_trap_check(tu); return returnValue; @@ -2950,18 +2953,18 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs1&&rs1(traits:: RFS)) { auto PC_val_v = tu.assignment("PC_val", tu.bitwise_and(tu.load(rs1%static_cast(traits:: RFS)+ traits::X0, 0),tu.constant(~ 0x1,8)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } else{ this->gen_raise_trap(tu, 0, 2); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,80); gen_trap_check(tu); return returnValue; @@ -2977,11 +2980,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); this->gen_raise_trap(tu, 0, 2); - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,81); gen_trap_check(tu); return returnValue; @@ -3002,6 +3005,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rd>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -3011,9 +3015,8 @@ private: tu.store(rd + traits::X0,tu.add(tu.load(rd+ traits::X0, 0),tu.load(rs2+ traits::X0, 0))); } } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,82); gen_trap_check(tu); return returnValue; @@ -3033,6 +3036,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs1>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -3042,11 +3046,10 @@ private: tu.store(1 + traits::X0,tu.add(tu.ext(cur_pc_val,32,false),tu.constant( 2,32))); auto PC_val_v = tu.assignment("PC_val", tu.bitwise_and(new_pc,tu.constant(~ 0x1,8)),32); tu.store(traits::NEXT_PC, PC_val_v); - auto noJump = tu.conditionalAssignment(tu.icmp(ICmpInst::ICMP_NE, tu.ext(PC_val_v, 32, true), tu.constant(pc.val, 32)),tu.constant(0U, 32), tu.constant(1U, 32)); - tu.store(traits::LAST_BRANCH, noJump); + tu.store(traits::LAST_BRANCH, tu.constant(1U, 1)); } - tu.close_scope(); auto returnValue = std::make_tuple(BRANCH); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,83); gen_trap_check(tu); return returnValue; @@ -3062,10 +3065,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); this->gen_raise_trap(tu, 0, 3); + auto returnValue = std::make_tuple(CONT); tu.close_scope(); - auto returnValue = std::make_tuple(BRANCH); vm_base::gen_sync(tu, POST_SYNC,84); gen_trap_check(tu); return returnValue; @@ -3086,6 +3090,7 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); if(rs2>=static_cast(traits:: RFS)) { this->gen_raise_trap(tu, 0, 2); @@ -3094,9 +3099,8 @@ private: auto offs = tu.assignment(tu.add(tu.load(2+ traits::X0, 0),tu.constant(uimm,8)),32); tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ traits::X0, 0),32,true)); } - tu.close_scope(); - gen_set_pc(tu, pc, traits::NEXT_PC); auto returnValue = std::make_tuple(CONT); + tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,85); gen_trap_check(tu); return returnValue; @@ -3112,10 +3116,11 @@ private: } auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+4; + gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); this->gen_raise_trap(tu, 0, 2); + auto returnValue = std::make_tuple(CONT); tu.close_scope(); - auto returnValue = std::make_tuple(BRANCH); vm_base::gen_sync(tu, POST_SYNC,86); gen_trap_check(tu); return returnValue; @@ -3160,20 +3165,20 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, // we fetch at max 4 byte, alignment is 2 enum {TRAP_ID=1<<16}; code_word_t insn = 0; - const typename traits::addr_t upper_bits = ~traits::PGMASK; + // const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); auto *const data = (uint8_t *)&insn; paddr = this->core.v2p(pc); - if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary - auto res = this->core.read(paddr, 2, data); - if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); - if ((insn & 0x3) == 0x3) { // this is a 32bit instruction - res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); - } - } else { +// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary +// auto res = this->core.read(paddr, 2, data); +// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); +// if ((insn & 0x3) == 0x3) { // this is a 32bit instruction +// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); +// } +// } else { auto res = this->core.read(paddr, 4, data); if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); - } +// } if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' // curr pc on stack ++inst_cnt;