diff --git a/riscv/gen_input/RV32IBase.core_desc b/riscv/gen_input/RV32IBase.core_desc index c768d8f..123e1d1 100644 --- a/riscv/gen_input/RV32IBase.core_desc +++ b/riscv/gen_input/RV32IBase.core_desc @@ -1,8 +1,6 @@ InsructionSet RV32IBase { constants { XLEN, - PCLEN, - XLEN_BIT_MASK:=0x1f, fence:=0, fencei:=1, fencevmal:=2, @@ -16,7 +14,7 @@ InsructionSet RV32IBase { registers { [31:0] X[XLEN], PC[XLEN](is_pc), - alias ZERO[XLEN] is X[0] + alias ZERO[XLEN] is X[0] } instructions { @@ -197,7 +195,7 @@ InsructionSet RV32IBase { SLL { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; - if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&XLEN_BIT_MASK); + if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&(XLEN-1)); } SLT { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; @@ -217,12 +215,12 @@ InsructionSet RV32IBase { SRL { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; - if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&XLEN_BIT_MASK); + if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&(XLEN-1)); } SRA { encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; - if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&XLEN_BIT_MASK); + if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&(XLEN-1)); } OR { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; @@ -279,8 +277,8 @@ InsructionSet RV32IBase { val csr_val[XLEN] <= CSR[csr]; CSR[csr] <= rs_val; // make sure Xrd is updated once CSR write succeeds - X[rd] <= csr_val; - } else { + X[rd] <= csr_val; + } else { CSR[csr] <= rs_val; } } diff --git a/riscv/gen_input/minres_rv.core_desc b/riscv/gen_input/minres_rv.core_desc index c0cb5f2..ca9301d 100644 --- a/riscv/gen_input/minres_rv.core_desc +++ b/riscv/gen_input/minres_rv.core_desc @@ -9,7 +9,6 @@ import "RV64IBase.core_desc" import "RV64A.core_desc" Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { - template:"vm_riscv.in.cpp"; constants { XLEN:=32; PCLEN:=32; @@ -36,7 +35,6 @@ Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32 Core RV64IA provides RV64IBase, RV64A, RV32A { - template:"vm_riscv.in.cpp"; constants { XLEN:=64; PCLEN:=64; diff --git a/riscv/gen_input/templates/incl-CORENAME.h.gtl b/riscv/gen_input/templates/incl-CORENAME.h.gtl index 7c6aad2..95052f8 100644 --- a/riscv/gen_input/templates/incl-CORENAME.h.gtl +++ b/riscv/gen_input/templates/incl-CORENAME.h.gtl @@ -1,34 +1,35 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2017, 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. -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * 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 @@ -39,18 +40,17 @@ def getTypeSize(size){ #ifndef _${coreDef.name.toUpperCase()}_H_ #define _${coreDef.name.toUpperCase()}_H_ +#include +#include #include #include -#include -#include namespace iss { namespace arch { struct ${coreDef.name.toLowerCase()}; -template<> -struct traits<${coreDef.name.toLowerCase()}> { +template <> struct traits<${coreDef.name.toLowerCase()}> { constexpr static char const* const core_type = "${coreDef.name}"; @@ -87,21 +87,21 @@ struct traits<${coreDef.name.toLowerCase()}> { using phys_addr_t = iss::typed_addr_t; - constexpr static unsigned reg_bit_width(unsigned r) { - constexpr std::array ${coreDef.name}_reg_size{{${regSizes.join(",")}}}; - return ${coreDef.name}_reg_size[r]; - } + static constexpr std::array ${coreDef.name}_reg_size{ + {${regSizes.join(",")}}}; - constexpr static unsigned reg_byte_offset(unsigned r) { - constexpr std::array ${coreDef.name}_reg_byte_offset{{${regOffsets.join(",")}}}; - return ${coreDef.name}_reg_byte_offset[r]; - } + static constexpr unsigned reg_bit_width(unsigned r) { return ${coreDef.name}_reg_size[r]; } + + static constexpr std::array ${coreDef.name}_reg_byte_offset{ + {${regOffsets.join(",")}}}; + + constexpr static unsigned reg_byte_offset(unsigned r) { return ${coreDef.name}_reg_byte_offset[r]; } static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); - enum sreg_flag_e {FLAGS}; + enum sreg_flag_e { FLAGS }; - enum mem_type_e {${allSpaces.collect{s -> s.name}.join(', ')}}; + enum mem_type_e { ${allSpaces.collect{s -> s.name}.join(', ')} }; }; struct ${coreDef.name.toLowerCase()}: public arch_if { @@ -126,12 +126,13 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { /// deprecated void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; - uint64_t get_icount() { return reg.icount;} + inline uint64_t get_icount() { return reg.icount; } + + inline bool should_stop() { 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){ + 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); @@ -141,8 +142,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 reg.last_branch;} + inline uint32_t get_last_branch() { return reg.last_branch; } protected: struct ${coreDef.name}_regs {<% diff --git a/riscv/gen_input/templates/src-CORENAME.cpp.gtl b/riscv/gen_input/templates/src-CORENAME.cpp.gtl index cafe82c..58d0342 100644 --- a/riscv/gen_input/templates/src-CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/src-CORENAME.cpp.gtl @@ -1,34 +1,34 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * 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. + * + *******************************************************************************/ #include "util/ities.h" #include @@ -43,30 +43,33 @@ extern "C" { #ifdef __cplusplus } #endif -#include #include #include +#include using namespace iss::arch; +constexpr std::array iss::arch::traits::${coreDef.name}_reg_size; +constexpr std::array iss::arch::traits::${coreDef.name}_reg_byte_offset; + ${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { - reg.icount=0; + reg.icount = 0; + reg.machine_state = 0x3; } -${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}(){ +${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default; } void ${coreDef.name.toLowerCase()}::reset(uint64_t address) { - for(size_t i=0; i::NUM_REGS; ++i) set_reg(i, std::vector(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0)); + 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=0x0; + reg.machine_state=0x3; } -uint8_t* ${coreDef.name.toLowerCase()}::get_regs_base_ptr(){ - return reinterpret_cast(®); -} +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/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl index b84bae6..b56fad8 100644 --- a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl @@ -1,38 +1,34 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2017, MINRES Technologies GmbH -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Contributors: -// eyck@minres.com - initial API and implementation -// -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * 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. + * + *******************************************************************************/ #include #include @@ -44,12 +40,12 @@ #include -#include #include +#include namespace iss { namespace vm { -namespace fp_impl{ +namespace fp_impl { void add_fp_functions_2_module(llvm::Module *, unsigned); } } @@ -73,7 +69,7 @@ public: void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } - target_adapter_if *accquire_target_adapter(server_if *srv) { + target_adapter_if *accquire_target_adapter(server_if *srv) override { debugger_if::dbg_enabled = true; if (vm::vm_base::tgt_adapter == nullptr) vm::vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); @@ -87,7 +83,7 @@ protected: return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); } - void setup_module(llvm::Module* m) override { + void setup_module(llvm::Module *m) override { super::setup_module(m); vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } @@ -117,7 +113,7 @@ protected: inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), - this->get_type(traits::XLEN)); + this->get_type(traits::XLEN)); this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); } @@ -136,9 +132,9 @@ protected: std::array lut_00, lut_01, lut_10; std::array lut_11; - std::array qlut; + std::array qlut; - std::array lutmasks = { { EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32 } }; + std::array lutmasks = {{EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32}}; void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[], compile_func f) { @@ -248,7 +244,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); try { - uint8_t *const data = (uint8_t *)&insn; + 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); @@ -282,7 +278,8 @@ template void vm_impl::gen_leave_behavior(llvm::BasicBlock template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_leave_trap(unsigned lvl) { @@ -292,7 +289,8 @@ template void vm_impl::gen_leave_trap(unsigned lvl) { this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_wait(unsigned type) { @@ -305,11 +303,10 @@ template void vm_impl::gen_wait(unsigned type) { template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - std::vector args{ - this->core_ptr, - this->adj_to64(trap_state_val), - this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); + std::vector args{this->core_ptr, this->adj_to64(trap_state_val), + this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateRet(trap_addr_val); @@ -327,10 +324,9 @@ template inline void vm_impl::gen_trap_check(llvm::BasicBl template <> std::unique_ptr create(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { - std::unique_ptr<${coreDef.name.toLowerCase()}::vm_impl> ret = - std::make_unique<${coreDef.name.toLowerCase()}::vm_impl>(*core, dump); - if (port != 0) debugger::server::run_server(ret.get(), port); - return ret; + auto ret = new ${coreDef.name.toLowerCase()}::vm_impl(*core, dump); + if (port != 0) debugger::server::run_server(ret, port); + return std::unique_ptr(ret); } } // namespace iss diff --git a/riscv/gen_input/templates/vm_riscv.in.cpp b/riscv/gen_input/templates/vm_riscv.in.cpp index d86bf14..46a9529 100644 --- a/riscv/gen_input/templates/vm_riscv.in.cpp +++ b/riscv/gen_input/templates/vm_riscv.in.cpp @@ -44,6 +44,12 @@ #include namespace iss { +namespace vm { +namespace fp_impl { +void add_fp_functions_2_module(llvm::Module *, unsigned); +} +} + namespace CORE_DEF_NAME { using namespace iss::arch; using namespace llvm; @@ -63,7 +69,7 @@ public: void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } - target_adapter_if *accquire_target_adapter(server_if *srv) { + target_adapter_if *accquire_target_adapter(server_if *srv) override { debugger_if::dbg_enabled = true; if (vm::vm_base::tgt_adapter == nullptr) vm::vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); @@ -77,8 +83,12 @@ protected: return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); } - inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, - unsigned size) const { + void setup_module(llvm::Module *m) override { + super::setup_module(m); + vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + } + + inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) { return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); } @@ -225,7 +235,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); try { - uint8_t *const data = (uint8_t *)&insn; + 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); @@ -242,7 +252,6 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, } if (insn == 0x0000006f || (insn & 0xffff) == 0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' // curr pc on stack - typename vm_impl::processing_pc_entry addr(*this, pc, paddr); ++inst_cnt; auto lut_val = extract_fields(insn); auto f = qlut[insn & 0x3][lut_val]; @@ -260,6 +269,8 @@ template void vm_impl::gen_leave_behavior(llvm::BasicBlock template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_leave_trap(unsigned lvl) { @@ -269,6 +280,8 @@ template void vm_impl::gen_leave_trap(unsigned lvl) { this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_wait(unsigned type) { @@ -281,6 +294,8 @@ template void vm_impl::gen_wait(unsigned type) { template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); std::vector args{this->core_ptr, this->adj_to64(trap_state_val), this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); @@ -298,12 +313,10 @@ template inline void vm_impl::gen_trap_check(llvm::BasicBl } // namespace CORE_DEF_NAME -template <> -std::unique_ptr create(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { - std::unique_ptr> ret = - std::make_unique>(*core, dump); - if (port != 0) debugger::server::run_server(ret.get(), port); - return ret; +template <> std::unique_ptr create(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { + auto ret = new CORE_DEF_NAME::vm_impl(*core, dump); + if (port != 0) debugger::server::run_server(ret, port); + return std::unique_ptr(ret); } } // namespace iss