Cleanup of templates
This commit is contained in:
		| @@ -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; | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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 <array> | ||||
| #include <iss/arch/traits.h> | ||||
| #include <iss/arch_if.h> | ||||
| #include <iss/vm_if.h> | ||||
| #include <iss/arch/traits.h> | ||||
| #include <array> | ||||
|  | ||||
| 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<iss::address_type::PHYSICAL>; | ||||
|  | ||||
|     constexpr static unsigned reg_bit_width(unsigned r) { | ||||
|         constexpr std::array<const uint32_t, ${regSizes.size}> ${coreDef.name}_reg_size{{${regSizes.join(",")}}}; | ||||
|         return ${coreDef.name}_reg_size[r]; | ||||
|     } | ||||
|  	static constexpr std::array<const uint32_t, ${regSizes.size}> ${coreDef.name}_reg_size{ | ||||
|  		{${regSizes.join(",")}}}; | ||||
|  | ||||
|     constexpr static unsigned reg_byte_offset(unsigned r) { | ||||
|     	constexpr std::array<const uint32_t, ${regOffsets.size}> ${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<const uint32_t, ${regOffsets.size}> ${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<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL){ | ||||
|         if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL || | ||||
|                 addr_mode[static_cast<uint16_t>(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 {<% | ||||
|   | ||||
| @@ -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 <util/logging.h> | ||||
| @@ -43,30 +43,33 @@ extern "C" { | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| #include <fstream> | ||||
| #include <cstdio> | ||||
| #include <cstring> | ||||
| #include <fstream> | ||||
|  | ||||
| using namespace iss::arch; | ||||
|  | ||||
| constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::${coreDef.name}_reg_size; | ||||
| constexpr std::array<const uint32_t, 40> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::${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<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0)); | ||||
|     for(size_t i=0; i<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i) | ||||
|     	set_reg(i, std::vector<uint8_t>(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*>(®); | ||||
| } | ||||
| uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { return reinterpret_cast<uint8_t*>(®); } | ||||
|  | ||||
| ${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 | ||||
|   | ||||
| @@ -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 <iss/arch/${coreDef.name.toLowerCase()}.h> | ||||
| #include <iss/arch/riscv_hart_msu_vp.h> | ||||
| @@ -44,12 +40,12 @@ | ||||
|  | ||||
| #include <boost/format.hpp> | ||||
|  | ||||
| #include <iss/debugger/riscv_target_adapter.h> | ||||
| #include <array> | ||||
| #include <iss/debugger/riscv_target_adapter.h> | ||||
|  | ||||
| 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<ARCH>::tgt_adapter == nullptr) | ||||
|             vm::vm_base<ARCH>::tgt_adapter = new riscv_target_adapter<ARCH>(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<ARCH>::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<ARCH>::XLEN, pc.val), | ||||
|                                                                   this->get_type(traits<ARCH>::XLEN)); | ||||
|                                                                  this->get_type(traits<ARCH>::XLEN)); | ||||
|         this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); | ||||
|     } | ||||
|  | ||||
| @@ -136,9 +132,9 @@ protected: | ||||
|     std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10; | ||||
|     std::array<compile_func, LUT_SIZE> lut_11; | ||||
|  | ||||
| 	std::array<compile_func*, 4> qlut; | ||||
| 	std::array<compile_func *, 4> qlut; | ||||
|  | ||||
| 	std::array<const uint32_t, 4> lutmasks = { { EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32 } }; | ||||
| 	std::array<const uint32_t, 4> 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<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, | ||||
|     const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::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 <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(llvm::BasicBlock | ||||
| template <typename ARCH> void vm_impl<ARCH>::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<ARCH>::TRAP_STATE), true); | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), | ||||
|     						  get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) { | ||||
| @@ -292,7 +289,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) { | ||||
|     this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); | ||||
|     auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8); | ||||
|     this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), | ||||
|                               get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) { | ||||
| @@ -305,11 +303,10 @@ template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) { | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(llvm::BasicBlock *trap_blk) { | ||||
|     this->builder.SetInsertPoint(trap_blk); | ||||
|     auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true); | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
|     std::vector<llvm::Value *> args{ | ||||
|     	this->core_ptr, | ||||
|     	this->adj_to64(trap_state_val), | ||||
|         this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))}; | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), | ||||
|                               get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
|     std::vector<llvm::Value *> args{this->core_ptr, this->adj_to64(trap_state_val), | ||||
|                                     this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))}; | ||||
|     this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); | ||||
|     auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|     this->builder.CreateRet(trap_addr_val); | ||||
| @@ -327,10 +324,9 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl | ||||
|  | ||||
| template <> | ||||
| std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { | ||||
|     std::unique_ptr<${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>> ret = | ||||
|         std::make_unique<${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>>(*core, dump); | ||||
|     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret.get(), port); | ||||
|     return ret; | ||||
|     auto ret = new ${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*core, dump); | ||||
|     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); | ||||
|     return std::unique_ptr<vm_if>(ret); | ||||
| } | ||||
|  | ||||
| } // namespace iss | ||||
|   | ||||
| @@ -44,6 +44,12 @@ | ||||
| #include <iss/debugger/riscv_target_adapter.h> | ||||
|  | ||||
| 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<ARCH>::tgt_adapter == nullptr) | ||||
|             vm::vm_base<ARCH>::tgt_adapter = new riscv_target_adapter<ARCH>(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<ARCH>::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<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, | ||||
|     const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::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<ARCH>::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<ARCH>::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 <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(llvm::BasicBlock | ||||
| template <typename ARCH> void vm_impl<ARCH>::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<ARCH>::TRAP_STATE), true); | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), | ||||
|                               get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) { | ||||
| @@ -269,6 +280,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) { | ||||
|     this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); | ||||
|     auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8); | ||||
|     this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), | ||||
|                               get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) { | ||||
| @@ -281,6 +294,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) { | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(llvm::BasicBlock *trap_blk) { | ||||
|     this->builder.SetInsertPoint(trap_blk); | ||||
|     auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true); | ||||
|     this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), | ||||
|                               get_reg_ptr(traits<ARCH>::LAST_BRANCH), false); | ||||
|     std::vector<llvm::Value *> args{this->core_ptr, this->adj_to64(trap_state_val), | ||||
|                                     this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))}; | ||||
|     this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); | ||||
| @@ -298,12 +313,10 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl | ||||
|  | ||||
| } // namespace CORE_DEF_NAME | ||||
|  | ||||
| template <> | ||||
| std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { | ||||
|     std::unique_ptr<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>> ret = | ||||
|         std::make_unique<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>>(*core, dump); | ||||
|     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret.get(), port); | ||||
|     return ret; | ||||
| template <> std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { | ||||
|     auto ret = new CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>(*core, dump); | ||||
|     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); | ||||
|     return std::unique_ptr<vm_if>(ret); | ||||
| } | ||||
|  | ||||
| } // namespace iss | ||||
|   | ||||
		Reference in New Issue
	
	Block a user