From aa8c2138c6622de47c26c30bf563e9bbcee798b8 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 21 Sep 2017 13:13:01 +0200 Subject: [PATCH] Added initial SystemC structure and removed easylogging --- CMakeLists.txt | 1 + cmake/Submodules.cmake | 6 +- riscv/fe310.rdl | 11 + riscv/gpio.rdl | 122 +++ riscv/incl/cli_options.h | 119 ++- riscv/incl/iss/arch/riscv_hart_msu_vp.h | 51 +- riscv/incl/iss/arch/rv32imac.h | 3 +- riscv/incl/sysc/SiFive/core_complex.h | 64 ++ riscv/incl/sysc/SiFive/gen/e300_plat_t.h | 11 + riscv/incl/sysc/SiFive/gen/gpio_regs.h | 159 +++ riscv/incl/sysc/SiFive/gen/plic_regs.h | 104 ++ riscv/incl/sysc/SiFive/gen/spi_regs.h | 199 ++++ riscv/incl/sysc/SiFive/gen/uart_regs.h | 132 +++ riscv/incl/sysc/SiFive/gpio.h | 42 + riscv/incl/sysc/SiFive/platform.h | 62 ++ riscv/incl/sysc/SiFive/plic.h | 42 + riscv/incl/sysc/SiFive/spi.h | 42 + riscv/incl/sysc/SiFive/uart.h | 42 + riscv/plic.rdl | 37 + riscv/src/CMakeLists.txt | 19 +- riscv/src/internal/vm_riscv.in.cpp | 29 +- riscv/src/internal/vm_rv32imac.cpp | 1228 +++------------------- riscv/src/iss/rv32imac.cpp | 2 +- riscv/src/main.cpp | 30 +- riscv/src/minres_rv.core_desc | 20 +- riscv/src/sc_main.cpp | 83 ++ riscv/src/sysc/core_complex.cpp | 55 + riscv/src/sysc/gpio.cpp | 50 + riscv/src/sysc/platform.cpp | 66 ++ riscv/src/sysc/plic.cpp | 51 + riscv/src/sysc/spi.cpp | 51 + riscv/src/sysc/uart.cpp | 51 + 32 files changed, 1810 insertions(+), 1174 deletions(-) create mode 100644 riscv/fe310.rdl create mode 100644 riscv/gpio.rdl create mode 100644 riscv/incl/sysc/SiFive/core_complex.h create mode 100644 riscv/incl/sysc/SiFive/gen/e300_plat_t.h create mode 100644 riscv/incl/sysc/SiFive/gen/gpio_regs.h create mode 100644 riscv/incl/sysc/SiFive/gen/plic_regs.h create mode 100644 riscv/incl/sysc/SiFive/gen/spi_regs.h create mode 100644 riscv/incl/sysc/SiFive/gen/uart_regs.h create mode 100644 riscv/incl/sysc/SiFive/gpio.h create mode 100644 riscv/incl/sysc/SiFive/platform.h create mode 100644 riscv/incl/sysc/SiFive/plic.h create mode 100644 riscv/incl/sysc/SiFive/spi.h create mode 100644 riscv/incl/sysc/SiFive/uart.h create mode 100644 riscv/plic.rdl create mode 100644 riscv/src/sc_main.cpp create mode 100644 riscv/src/sysc/core_complex.cpp create mode 100644 riscv/src/sysc/gpio.cpp create mode 100644 riscv/src/sysc/platform.cpp create mode 100644 riscv/src/sysc/plic.cpp create mode 100644 riscv/src/sysc/spi.cpp create mode 100644 riscv/src/sysc/uart.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index af30b57..3b83bf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ set(GIT_SUBMODULE_DIR_dbt-core .) ### set each submodules's commit or tag that is to be checked out ### (leave empty if you want master) #set(GIT_SUBMODULE_VERSION_sc-comp 3af6b9836589b082c19d9131c5d0b7afa8ddd7cd) +set(GIT_SUBMODULE_BRANCH_sc-components "develop") include(GNUInstallDirs) include(cmake/Submodules.cmake) diff --git a/cmake/Submodules.cmake b/cmake/Submodules.cmake index f2612b8..0d1b89d 100644 --- a/cmake/Submodules.cmake +++ b/cmake/Submodules.cmake @@ -24,7 +24,11 @@ foreach(GIT_SUBMODULE ${GIT_SUBMODULES}) if( "${GIT_SUBMODULE_VERSION_${GIT_SUBMODULE}}" STREQUAL "" ) message(STATUS "no specific version given for submodule ${GIT_SUBMODULE}, checking out master") - set(GIT_SUBMODULE_VERSION_${GIT_SUBMODULE} "master") + if( "${GIT_SUBMODULE_BRANCH_${GIT_SUBMODULE}}" STREQUAL "" ) + set(GIT_SUBMODULE_VERSION_${GIT_SUBMODULE} "master") + else() + set(GIT_SUBMODULE_VERSION_${GIT_SUBMODULE} ${GIT_SUBMODULE_BRANCH_${GIT_SUBMODULE}}) + endif() endif() if( "${GIT_SUBMODULE_DIR_${GIT_SUBMODULE}}" STREQUAL "" ) diff --git a/riscv/fe310.rdl b/riscv/fe310.rdl new file mode 100644 index 0000000..e355d2b --- /dev/null +++ b/riscv/fe310.rdl @@ -0,0 +1,11 @@ +`include "gpio.rdl" +`include "uart.rdl" +`include "spi.rdl" +`include "plic.rdl" + +addrmap e300_plat_t { + plic_regs plic @0x0C000000; + gpio_regs gpio @0x10012000; + uart_regs uart @0x10013000; + spi_regs spi @0x10014000; +} e300_plat; diff --git a/riscv/gpio.rdl b/riscv/gpio.rdl new file mode 100644 index 0000000..6137c0f --- /dev/null +++ b/riscv/gpio.rdl @@ -0,0 +1,122 @@ +regfile gpio_regs { + lsb0; + reg { + name="value"; + desc="pin value"; + field { + name = "data"; + } data[31:0]; + } value @0x000; + reg { + name="input_en"; + desc="* pin input enable"; + field { + name = "data"; + } data[31:0]; + } input_en @0x004; + reg { + name="output_en"; + desc="pin output enable"; + field { + name = "data"; + } data[31:0]; + } output_en @0x008; + reg { + name="port"; + desc="output port value"; + field { + name = "data"; + } data[31:0]; + } port @0x00C; + reg { + name="pue"; + desc="internal pull-up enable"; + field { + name = "data"; + } data[31:0]; + } pue @0x010; + reg { + name="ds"; + desc="Pin Drive Strength"; + field { + name = "data"; + } data[31:0]; + } ds @0x014; + reg { + name="rise_ie"; + desc="rise interrupt enable"; + field { + name = "data"; + } data[31:0]; + } rise_ie @0x018; + reg { + name="rise_ip"; + desc="rise interrupt pending"; + field { + name = "data"; + } data[31:0]; + } rise_ip @0x01C; + reg { + name="fall_ie"; + desc="fall interrupt enable"; + field { + name = "data"; + } data[31:0]; + } fall_ie @0x020; + reg { + name="fall_ip"; + desc="fall interrupt pending"; + field { + name = "data"; + } data[31:0]; + } fall_ip @0x024; + reg { + name="high_ie"; + desc="high interrupt enable"; + field { + name = "data"; + } data[31:0]; + } high_ie @0x028; + reg { + name="high_ip"; + desc="high interrupt pending"; + field { + name = "data"; + } data[31:0]; + } high_ip @0x02C; + reg { + name="low_ie"; + desc="low interrupt enable"; + field { + name = "data"; + } data[31:0]; + } low_ie @0x030; + reg { + name="low_ip"; + desc="low interrupt pending"; + field { + name = "data"; + } data[31:0]; + } low_ip @0x034; + reg { + name="iof_en"; + desc="HW I/O Function enable"; + field { + name = "data"; + } data[31:0]; + } iof_en @0x038; + reg { + name="iof_sel"; + desc="HW I/O Function select"; + field { + name = "data"; + } data[31:0]; + } iof_sel @0x03C; + reg { + name="out_xor"; + desc="Output XOR (invert)"; + field { + name = "data"; + } data[31:0]; + } out_xor @0x040; +}; \ No newline at end of file diff --git a/riscv/incl/cli_options.h b/riscv/incl/cli_options.h index 78e3d0a..9e02585 100644 --- a/riscv/incl/cli_options.h +++ b/riscv/incl/cli_options.h @@ -35,7 +35,9 @@ #ifndef _CLI_OPTIONS_H_ #define _CLI_OPTIONS_H_ #include -#include +#include +#include +#include namespace { const size_t ERROR_IN_COMMAND_LINE = 1; @@ -43,88 +45,88 @@ const size_t SUCCESS = 0; const size_t ERROR_UNHANDLED_EXCEPTION = 2; -inline void enable_log_level(el::Configurations& conf, int level){ +inline void enable_log_level(int level){ switch(level){ case 0: - conf.set(el::Level::Fatal, el::ConfigurationType::Enabled, "false"); + logging::Logger::reporting_level()= logging::FATAL; /* no break */ case 1: - conf.set(el::Level::Error, el::ConfigurationType::Enabled, "false"); + logging::Logger::reporting_level()= logging::ERROR; /* no break */ case 2: - conf.set(el::Level::Warning, el::ConfigurationType::Enabled, "false"); + logging::Logger::reporting_level()= logging::WARNING; /* no break */ case 3: - conf.set(el::Level::Info, el::ConfigurationType::Enabled, "false"); + logging::Logger::reporting_level()= logging::INFO; /* no break */ case 4: - conf.set(el::Level::Debug, el::ConfigurationType::Enabled, "false"); + logging::Logger::reporting_level()= logging::DEBUG; /* no break */ case 5: - conf.set(el::Level::Trace, el::ConfigurationType::Enabled, "false"); + logging::Logger::reporting_level()= logging::TRACE; /* no break */ } } inline void configure_default_logger(boost::program_options::variables_map& vm){ - el::Configurations defaultConf; - defaultConf.setToDefault(); - defaultConf.set(el::Level::Error, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); - defaultConf.set(el::Level::Warning, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); - defaultConf.set(el::Level::Info, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); - defaultConf.set(el::Level::Debug, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); - defaultConf.set(el::Level::Trace, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); +// el::Configurations defaultConf; +// defaultConf.setToDefault(); +// defaultConf.set(el::Level::Error, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); +// defaultConf.set(el::Level::Warning, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); +// defaultConf.set(el::Level::Info, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); +// defaultConf.set(el::Level::Debug, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); +// defaultConf.set(el::Level::Trace, el::ConfigurationType::Format, "%datetime{%H:%m:%s.%g} %level %msg"); if(vm.count("verbose")) - enable_log_level(defaultConf, vm["verbose"].as()); + enable_log_level(vm["verbose"].as()); if(vm.count("log-file")) - defaultConf.set(el::Level::Global,el::ConfigurationType::Filename, vm["log-file"].as()); + logging::Output2FILE::stream() = fopen(vm["log-file"].as().c_str(), "w"); // default logger uses default configurations - el::Loggers::reconfigureLogger("default", defaultConf); +// el::Loggers::reconfigureLogger("default", defaultConf); } inline void configure_debugger_logger() { // configure the connection logger - el::Logger* gdbServerLogger = el::Loggers::getLogger("connection"); - el::Configurations gdbServerConf; - gdbServerConf.setToDefault(); - gdbServerConf.set(el::Level::Error, el::ConfigurationType::Format, - "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); - gdbServerConf.set(el::Level::Warning, el::ConfigurationType::Format, - "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); - gdbServerConf.set(el::Level::Info, el::ConfigurationType::Format, - "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); - gdbServerConf.set(el::Level::Debug, el::ConfigurationType::Format, - "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); - gdbServerConf.set(el::Level::Trace, el::ConfigurationType::Format, - "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); - enable_log_level(gdbServerConf, 5); - gdbServerLogger->configure(gdbServerConf); +// el::Logger* gdbServerLogger = el::Loggers::getLogger("connection"); +// el::Configurations gdbServerConf; +// gdbServerConf.setToDefault(); +// gdbServerConf.set(el::Level::Error, el::ConfigurationType::Format, +// "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); +// gdbServerConf.set(el::Level::Warning, el::ConfigurationType::Format, +// "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); +// gdbServerConf.set(el::Level::Info, el::ConfigurationType::Format, +// "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); +// gdbServerConf.set(el::Level::Debug, el::ConfigurationType::Format, +// "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); +// gdbServerConf.set(el::Level::Trace, el::ConfigurationType::Format, +// "%datetime{%H:%m:%s.%g} %level [%logger] %msg"); +// enable_log_level(gdbServerConf, 5); +// gdbServerLogger->configure(gdbServerConf); } inline void configure_disass_logger(boost::program_options::variables_map& vm) { - el::Logger* disassLogger = el::Loggers::getLogger("disass"); - el::Configurations disassConf; - if(vm.count("disass")){ - auto file_name=vm["disass"].as(); - disassConf.setToDefault(); - if (file_name.length() > 0) { - disassConf.set(el::Level::Global, el::ConfigurationType::ToFile, - std::string("true")); - disassConf.set(el::Level::Global, - el::ConfigurationType::ToStandardOutput, std::string("false")); - disassConf.set(el::Level::Global, el::ConfigurationType::Format, - std::string("%msg")); - disassConf.set(el::Level::Global, el::ConfigurationType::Filename, - file_name); - std::ofstream str(file_name); // just to clear the file - } else { - disassConf.set(el::Level::Global, el::ConfigurationType::Format, - "%datetime{%H:%m:%s.%g} [%logger] %msg"); - } - } else { - enable_log_level(disassConf, 0); - } - disassLogger->configure(disassConf); +// el::Logger* disassLogger = el::Loggers::getLogger("disass"); +// el::Configurations disassConf; +// if(vm.count("disass")){ +// auto file_name=vm["disass"].as(); +// disassConf.setToDefault(); +// if (file_name.length() > 0) { +// disassConf.set(el::Level::Global, el::ConfigurationType::ToFile, +// std::string("true")); +// disassConf.set(el::Level::Global, +// el::ConfigurationType::ToStandardOutput, std::string("false")); +// disassConf.set(el::Level::Global, el::ConfigurationType::Format, +// std::string("%msg")); +// disassConf.set(el::Level::Global, el::ConfigurationType::Filename, +// file_name); +// std::ofstream str(file_name); // just to clear the file +// } else { +// disassConf.set(el::Level::Global, el::ConfigurationType::Format, +// "%datetime{%H:%m:%s.%g} [%logger] %msg"); +// } +// } else { +// enable_log_level(disassConf, 0); +// } +// disassLogger->configure(disassConf); } } // namespace @@ -148,12 +150,13 @@ inline int parse_cli_options(boost::program_options::variables_map& vm, int argc ("time", po::value(), "SystemC siimulation time in ms") ("reset,r", po::value(), "reset address") ("trace", po::value(), "enable tracing, or cmbintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite")\ - ("mem,m", po::value(), "the memory input file"); + ("mem,m", po::value(), "the memory input file") + ("rv64", "run RV64"); try { po::store(po::parse_command_line(argc, argv, desc), vm); // can throw // --help option if ( vm.count("help") ){ - std::cout << "JIT-ISS simulator for AVR" << std::endl << desc << std::endl; + std::cout << "DBT-RISE-RiscV" << std::endl << desc << std::endl; return SUCCESS; } po::notify(vm); // throws on error, so do after help in case diff --git a/riscv/incl/iss/arch/riscv_hart_msu_vp.h b/riscv/incl/iss/arch/riscv_hart_msu_vp.h index e4f9913..528368a 100644 --- a/riscv/incl/iss/arch/riscv_hart_msu_vp.h +++ b/riscv/incl/iss/arch/riscv_hart_msu_vp.h @@ -40,8 +40,10 @@ #include #include #include -#include +#include #include +#include +#include namespace iss { namespace arch { @@ -156,7 +158,9 @@ enum csr_name { dscratch=0x7B2 }; -char lvl[]={'U', 'S', 'H', 'M'}; +namespace { + +const char lvl[]={'U', 'S', 'H', 'M'}; const char* trap_str[] = { "Instruction address misaligned", @@ -191,7 +195,6 @@ const char* irq_str[] = { "Machine external interrupt" }; -namespace { enum { PGSHIFT=12, PTE_PPN_SHIFT=10, @@ -500,8 +503,7 @@ struct riscv_hart_msu_vp: public BASE { virtual std::string get_additional_disass_info(){ std::stringstream s; - auto status = csr[mstatus]; - s<<"[p:"<reg.machine_state]<<";s:0x"<reg.icount<<"]"; + s<<"[p:"<reg.machine_state]<<";s:0x"<reg.icount<<"]"; return s.str(); }; @@ -521,6 +523,7 @@ protected: using csr_page_type = typename csr_type::page_type; mem_type mem; csr_type csr; + reg_t& mstatus_r, satp_r; unsigned to_host_wr_cnt=0; std::stringstream uart_buf; std::unordered_map ptw; @@ -542,7 +545,7 @@ private: }; template -riscv_hart_msu_vp::riscv_hart_msu_vp() { +riscv_hart_msu_vp::riscv_hart_msu_vp() : mstatus_r(csr[mstatus]), satp_r(csr[satp]) { csr[misa]=traits::XLEN==32?1ULL<<(traits::XLEN-2):2ULL<<(traits::XLEN-2); uart_buf.str(""); // read-only registers @@ -624,9 +627,9 @@ template iss::status riscv_hart_msu_vp::read(const iss::addr_t& addr, unsigned length, uint8_t* const data){ #ifndef NDEBUG if(addr.type& iss::DEBUG){ - LOG(DEBUG)<<"debug read of "<::write(const iss::addr_t& addr, unsigned len const char* prefix = addr.type & iss::DEBUG?"debug ":""; switch(length){ case 8: - LOG(DEBUG)<::write_mem(phys_addr_t addr, unsigned length if(tohost_upper || (tohost_lower && to_host_wr_cnt>0)){ switch(hostvar>>48){ case 0: - (hostvar!=0x1?LOG(FATAL):LOG(INFO))<<"tohost value is 0x"<(hostvar & 0xff); if(c=='\n' || c==0){ - LOG(INFO)<<"tohost send '"<::phys_addr_t riscv_hart_msu_vp::v2p(const return ret; } - const reg_t mstatus_r = csr[mstatus]; const access_type type = (access_type)(addr.getAccessType()&~iss::DEBUG); uint32_t mode =type != iss::FETCH && bit_sub<17,1>(mstatus_r)? // MPRV mode = bit_sub<11,2>(mstatus_r):// MPV this->reg.machine_state; - const vm_info vm = decode_vm_info::XLEN>(mode, csr[satp]); + const vm_info vm = decode_vm_info::XLEN>(mode, satp_r); if (vm.levels == 0){ phys_addr_t ret(addr); @@ -1185,12 +1189,8 @@ uint64_t riscv_hart_msu_vp::enter_trap(uint64_t flags, uint64_t addr) { this->reg.trap_state=0; char buffer[32]; sprintf(buffer, "0x%016lx", addr); - if(trap_id) - el::Loggers::getLogger("disass", true)->info("Interrupt %v with cause '%v' at address %v occurred, changing privilege level from %v to %v", - trap_id, irq_str[cause], buffer , lvl[cur_priv], lvl[new_priv]); - else - el::Loggers::getLogger("disass", true)->info("Trap %v with cause '%v' at address %v occurred, changing privilege level from %v to %v", - trap_id, trap_str[cause], buffer , lvl[cur_priv], lvl[new_priv]); + CLOG(logging::INFO, "disass")<<(trap_id?"Interrupt ":"Trap ")<reg.NEXT_PC; } @@ -1229,8 +1229,7 @@ uint64_t riscv_hart_msu_vp::leave_trap(uint64_t flags) { status|= pie<reg.machine_state=ppl; - el::Loggers::getLogger("disass", true)->info("Executing xRET , changing privilege level from %v to %v", - lvl[cur_priv], lvl[ppl]); + CLOG(logging::INFO, "disass")<<"Executing xRET , changing privilege level from "<reg.NEXT_PC; } diff --git a/riscv/incl/iss/arch/rv32imac.h b/riscv/incl/iss/arch/rv32imac.h index b2c9644..77c476c 100644 --- a/riscv/incl/iss/arch/rv32imac.h +++ b/riscv/incl/iss/arch/rv32imac.h @@ -28,7 +28,7 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // -// Created on: Tue Aug 29 16:45:20 CEST 2017 +// Created on: Tue Sep 05 18:57:24 CEST 2017 // * rv32imac.h Author: // //////////////////////////////////////////////////////////////////////////////// @@ -144,6 +144,7 @@ struct rv32imac: public arch_if { if(phase==ISTART){ ++reg.icount; reg.PC=reg.NEXT_PC; + reg.trap_state=reg.pending_trap; } } diff --git a/riscv/incl/sysc/SiFive/core_complex.h b/riscv/incl/sysc/SiFive/core_complex.h new file mode 100644 index 0000000..8e6ef28 --- /dev/null +++ b/riscv/incl/sysc/SiFive/core_complex.h @@ -0,0 +1,64 @@ + //////////////////////////////////////////////////////////////////////////////// +// 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 +// +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _SYSC_SIFIVE_FE310_H_ +#define _SYSC_SIFIVE_FE310_H_ + +#include +#include +#include +#include + +namespace sysc { +namespace SiFive { + +class core_complex: + public iss::arch::riscv_hart_msu_vp, + public sc_core::sc_module { +public: + + tlm::tlm_initiator_socket<32> initiator; + + sc_core::sc_in rst_i; + core_complex(sc_core::sc_module_name name); + virtual ~core_complex(); + +}; + +} /* namespace SiFive */ +} /* namespace sysc */ + +#endif /* _SYSC_SIFIVE_FE310_H_ */ diff --git a/riscv/incl/sysc/SiFive/gen/e300_plat_t.h b/riscv/incl/sysc/SiFive/gen/e300_plat_t.h new file mode 100644 index 0000000..cfb8984 --- /dev/null +++ b/riscv/incl/sysc/SiFive/gen/e300_plat_t.h @@ -0,0 +1,11 @@ +#ifndef _E300_PLAT_MAP_H_ +#define _E300_PLAT_MAP_H_ +// need double braces, see https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 +const std::array, 4> e300_plat_map = {{ + {&i_plic, 0xc000000, 0x1000}, + {&i_gpio, 0x10012000, 0x1000}, + {&i_uart, 0x10013000, 0x1000}, + {&i_spi, 0x10014000, 0x1000}, +}}; + +#endif /* _E300_PLAT_MAP_H_ */ diff --git a/riscv/incl/sysc/SiFive/gen/gpio_regs.h b/riscv/incl/sysc/SiFive/gen/gpio_regs.h new file mode 100644 index 0000000..5e39a83 --- /dev/null +++ b/riscv/incl/sysc/SiFive/gen/gpio_regs.h @@ -0,0 +1,159 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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. +// +// Created on: Wed Sep 20 11:47:24 CEST 2017 +// * gpio_regs.h Author: +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _GPIO_REGS_H_ +#define _GPIO_REGS_H_ + +#include +#include +#include +#include + +namespace sysc { + +class gpio_regs : + public sc_core::sc_module, + public sysc::resetable +{ +protected: + // storage declarations + uint32_t r_value; + + uint32_t r_input_en; + + uint32_t r_output_en; + + uint32_t r_port; + + uint32_t r_pue; + + uint32_t r_ds; + + uint32_t r_rise_ie; + + uint32_t r_rise_ip; + + uint32_t r_fall_ie; + + uint32_t r_fall_ip; + + uint32_t r_high_ie; + + uint32_t r_high_ip; + + uint32_t r_low_ie; + + uint32_t r_low_ip; + + uint32_t r_iof_en; + + uint32_t r_iof_sel; + + uint32_t r_out_xor; + + // register declarations + sysc::sc_register value; + sysc::sc_register input_en; + sysc::sc_register output_en; + sysc::sc_register port; + sysc::sc_register pue; + sysc::sc_register ds; + sysc::sc_register rise_ie; + sysc::sc_register rise_ip; + sysc::sc_register fall_ie; + sysc::sc_register fall_ip; + sysc::sc_register high_ie; + sysc::sc_register high_ip; + sysc::sc_register low_ie; + sysc::sc_register low_ip; + sysc::sc_register iof_en; + sysc::sc_register iof_sel; + sysc::sc_register out_xor; + +public: + gpio_regs(sc_core::sc_module_name nm); + + template + void registerResources(sysc::tlm_target& target); +}; +} +////////////////////////////////////////////////////////////////////////////// +// member functions +////////////////////////////////////////////////////////////////////////////// + +inline sysc::gpio_regs::gpio_regs(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, NAMED(value, r_value, 0, *this) +, NAMED(input_en, r_input_en, 0, *this) +, NAMED(output_en, r_output_en, 0, *this) +, NAMED(port, r_port, 0, *this) +, NAMED(pue, r_pue, 0, *this) +, NAMED(ds, r_ds, 0, *this) +, NAMED(rise_ie, r_rise_ie, 0, *this) +, NAMED(rise_ip, r_rise_ip, 0, *this) +, NAMED(fall_ie, r_fall_ie, 0, *this) +, NAMED(fall_ip, r_fall_ip, 0, *this) +, NAMED(high_ie, r_high_ie, 0, *this) +, NAMED(high_ip, r_high_ip, 0, *this) +, NAMED(low_ie, r_low_ie, 0, *this) +, NAMED(low_ip, r_low_ip, 0, *this) +, NAMED(iof_en, r_iof_en, 0, *this) +, NAMED(iof_sel, r_iof_sel, 0, *this) +, NAMED(out_xor, r_out_xor, 0, *this) +{ +} + +template +inline void sysc::gpio_regs::registerResources(sysc::tlm_target& target) { + target.addResource(value, 0x0UL); + target.addResource(input_en, 0x4UL); + target.addResource(output_en, 0x8UL); + target.addResource(port, 0xcUL); + target.addResource(pue, 0x10UL); + target.addResource(ds, 0x14UL); + target.addResource(rise_ie, 0x18UL); + target.addResource(rise_ip, 0x1cUL); + target.addResource(fall_ie, 0x20UL); + target.addResource(fall_ip, 0x24UL); + target.addResource(high_ie, 0x28UL); + target.addResource(high_ip, 0x2cUL); + target.addResource(low_ie, 0x30UL); + target.addResource(low_ip, 0x34UL); + target.addResource(iof_en, 0x38UL); + target.addResource(iof_sel, 0x3cUL); + target.addResource(out_xor, 0x40UL); +} + +#endif // _GPIO_REGS_H_ diff --git a/riscv/incl/sysc/SiFive/gen/plic_regs.h b/riscv/incl/sysc/SiFive/gen/plic_regs.h new file mode 100644 index 0000000..936873c --- /dev/null +++ b/riscv/incl/sysc/SiFive/gen/plic_regs.h @@ -0,0 +1,104 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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. +// +// Created on: Wed Sep 20 22:30:45 CEST 2017 +// * plic_regs.h Author: +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _PLIC_REGS_H_ +#define _PLIC_REGS_H_ + +#include +#include +#include +#include + +namespace sysc { + +class plic_regs : + public sc_core::sc_module, + public sysc::resetable +{ +protected: + // storage declarations + BEGIN_BF_DECL(priority_t, uint32_t); + BF_FIELD(priority, 0, 3); + END_BF_DECL() ; + std::array r_priority; + + uint32_t r_pending; + + uint32_t r_enabled; + + BEGIN_BF_DECL(threshold_t, uint32_t); + BF_FIELD(threshold, 0, 3); + END_BF_DECL() r_threshold; + + uint32_t r_claim_complete; + + // register declarations + sysc::sc_register_indexed priority; + sysc::sc_register pending; + sysc::sc_register enabled; + sysc::sc_register threshold; + sysc::sc_register claim_complete; + +public: + plic_regs(sc_core::sc_module_name nm); + + template + void registerResources(sysc::tlm_target& target); +}; +} +////////////////////////////////////////////////////////////////////////////// +// member functions +////////////////////////////////////////////////////////////////////////////// + +inline sysc::plic_regs::plic_regs(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, NAMED(priority, r_priority, 0, *this) +, NAMED(pending, r_pending, 0, *this) +, NAMED(enabled, r_enabled, 0, *this) +, NAMED(threshold, r_threshold, 0, *this) +, NAMED(claim_complete, r_claim_complete, 0, *this) +{ +} + +template +inline void sysc::plic_regs::registerResources(sysc::tlm_target& target) { + target.addResource(priority, 0x4UL); + target.addResource(pending, 0x1000UL); + target.addResource(enabled, 0x2000UL); + target.addResource(threshold, 0xc200000UL); + target.addResource(claim_complete, 0xc200004UL); +} + +#endif // _PLIC_REGS_H_ diff --git a/riscv/incl/sysc/SiFive/gen/spi_regs.h b/riscv/incl/sysc/SiFive/gen/spi_regs.h new file mode 100644 index 0000000..4eb38ef --- /dev/null +++ b/riscv/incl/sysc/SiFive/gen/spi_regs.h @@ -0,0 +1,199 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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. +// +// Created on: Wed Sep 20 22:30:45 CEST 2017 +// * spi_regs.h Author: +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _SPI_REGS_H_ +#define _SPI_REGS_H_ + +#include +#include +#include +#include + +namespace sysc { + +class spi_regs : + public sc_core::sc_module, + public sysc::resetable +{ +protected: + // storage declarations + BEGIN_BF_DECL(sckdiv_t, uint32_t); + BF_FIELD(div, 0, 12); + END_BF_DECL() r_sckdiv; + + BEGIN_BF_DECL(sckmode_t, uint32_t); + BF_FIELD(pha, 0, 1); + BF_FIELD(pol, 1, 1); + END_BF_DECL() r_sckmode; + + uint32_t r_csid; + + uint32_t r_csdef; + + BEGIN_BF_DECL(csmode_t, uint32_t); + BF_FIELD(mode, 0, 2); + END_BF_DECL() r_csmode; + + BEGIN_BF_DECL(delay0_t, uint32_t); + BF_FIELD(cssck, 0, 8); + BF_FIELD(sckcs, 16, 8); + END_BF_DECL() r_delay0; + + BEGIN_BF_DECL(delay1_t, uint32_t); + BF_FIELD(intercs, 0, 16); + BF_FIELD(interxfr, 16, 8); + END_BF_DECL() r_delay1; + + BEGIN_BF_DECL(fmt_t, uint32_t); + BF_FIELD(proto, 0, 2); + BF_FIELD(endian, 2, 1); + BF_FIELD(dir, 3, 1); + BF_FIELD(len, 16, 4); + END_BF_DECL() r_fmt; + + BEGIN_BF_DECL(txdata_t, uint32_t); + BF_FIELD(data, 0, 8); + BF_FIELD(full, 31, 1); + END_BF_DECL() r_txdata; + + BEGIN_BF_DECL(rxdata_t, uint32_t); + BF_FIELD(data, 0, 8); + BF_FIELD(empty, 31, 1); + END_BF_DECL() r_rxdata; + + BEGIN_BF_DECL(txmark_t, uint32_t); + BF_FIELD(txmark, 0, 3); + END_BF_DECL() r_txmark; + + BEGIN_BF_DECL(rxmark_t, uint32_t); + BF_FIELD(rxmark, 0, 3); + END_BF_DECL() r_rxmark; + + BEGIN_BF_DECL(fctrl_t, uint32_t); + BF_FIELD(en, 0, 1); + END_BF_DECL() r_fctrl; + + BEGIN_BF_DECL(ffmt_t, uint32_t); + BF_FIELD(cmd_en, 0, 1); + BF_FIELD(addr_len, 1, 2); + BF_FIELD(pad_cnt, 3, 4); + BF_FIELD(cmd_proto, 7, 2); + BF_FIELD(addr_proto, 9, 2); + BF_FIELD(data_proto, 11, 2); + BF_FIELD(cmd_code, 16, 8); + BF_FIELD(pad_code, 24, 8); + END_BF_DECL() r_ffmt; + + BEGIN_BF_DECL(ie_t, uint32_t); + BF_FIELD(txwm, 0, 1); + BF_FIELD(rxwm, 1, 1); + END_BF_DECL() r_ie; + + BEGIN_BF_DECL(ip_t, uint32_t); + BF_FIELD(txwm, 0, 1); + BF_FIELD(rxwm, 1, 1); + END_BF_DECL() r_ip; + + // register declarations + sysc::sc_register sckdiv; + sysc::sc_register sckmode; + sysc::sc_register csid; + sysc::sc_register csdef; + sysc::sc_register csmode; + sysc::sc_register delay0; + sysc::sc_register delay1; + sysc::sc_register fmt; + sysc::sc_register txdata; + sysc::sc_register rxdata; + sysc::sc_register txmark; + sysc::sc_register rxmark; + sysc::sc_register fctrl; + sysc::sc_register ffmt; + sysc::sc_register ie; + sysc::sc_register ip; + +public: + spi_regs(sc_core::sc_module_name nm); + + template + void registerResources(sysc::tlm_target& target); +}; +} +////////////////////////////////////////////////////////////////////////////// +// member functions +////////////////////////////////////////////////////////////////////////////// + +inline sysc::spi_regs::spi_regs(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, NAMED(sckdiv, r_sckdiv, 0, *this) +, NAMED(sckmode, r_sckmode, 0, *this) +, NAMED(csid, r_csid, 0, *this) +, NAMED(csdef, r_csdef, 0, *this) +, NAMED(csmode, r_csmode, 0, *this) +, NAMED(delay0, r_delay0, 0, *this) +, NAMED(delay1, r_delay1, 0, *this) +, NAMED(fmt, r_fmt, 0, *this) +, NAMED(txdata, r_txdata, 0, *this) +, NAMED(rxdata, r_rxdata, 0, *this) +, NAMED(txmark, r_txmark, 0, *this) +, NAMED(rxmark, r_rxmark, 0, *this) +, NAMED(fctrl, r_fctrl, 0, *this) +, NAMED(ffmt, r_ffmt, 0, *this) +, NAMED(ie, r_ie, 0, *this) +, NAMED(ip, r_ip, 0, *this) +{ +} + +template +inline void sysc::spi_regs::registerResources(sysc::tlm_target& target) { + target.addResource(sckdiv, 0x0UL); + target.addResource(sckmode, 0x4UL); + target.addResource(csid, 0x10UL); + target.addResource(csdef, 0x14UL); + target.addResource(csmode, 0x18UL); + target.addResource(delay0, 0x28UL); + target.addResource(delay1, 0x2cUL); + target.addResource(fmt, 0x40UL); + target.addResource(txdata, 0x48UL); + target.addResource(rxdata, 0x4cUL); + target.addResource(txmark, 0x50UL); + target.addResource(rxmark, 0x54UL); + target.addResource(fctrl, 0x60UL); + target.addResource(ffmt, 0x64UL); + target.addResource(ie, 0x70UL); + target.addResource(ip, 0x74UL); +} + +#endif // _SPI_REGS_H_ diff --git a/riscv/incl/sysc/SiFive/gen/uart_regs.h b/riscv/incl/sysc/SiFive/gen/uart_regs.h new file mode 100644 index 0000000..87382b4 --- /dev/null +++ b/riscv/incl/sysc/SiFive/gen/uart_regs.h @@ -0,0 +1,132 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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. +// +// Created on: Wed Sep 20 22:30:45 CEST 2017 +// * uart_regs.h Author: +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _UART_REGS_H_ +#define _UART_REGS_H_ + +#include +#include +#include +#include + +namespace sysc { + +class uart_regs : + public sc_core::sc_module, + public sysc::resetable +{ +protected: + // storage declarations + BEGIN_BF_DECL(txdata_t, uint32_t); + BF_FIELD(data, 0, 8); + BF_FIELD(full, 31, 1); + END_BF_DECL() r_txdata; + + BEGIN_BF_DECL(rxdata_t, uint32_t); + BF_FIELD(data, 0, 8); + BF_FIELD(empty, 31, 1); + END_BF_DECL() r_rxdata; + + BEGIN_BF_DECL(txctrl_t, uint32_t); + BF_FIELD(txen, 0, 1); + BF_FIELD(nstop, 1, 1); + BF_FIELD(reserved, 2, 14); + BF_FIELD(txcnt, 16, 3); + END_BF_DECL() r_txctrl; + + BEGIN_BF_DECL(rxctrl_t, uint32_t); + BF_FIELD(rxen, 0, 1); + BF_FIELD(reserved, 1, 15); + BF_FIELD(rxcnt, 16, 3); + END_BF_DECL() r_rxctrl; + + BEGIN_BF_DECL(ie_t, uint32_t); + BF_FIELD(txwm, 0, 1); + BF_FIELD(rxwm, 1, 1); + END_BF_DECL() r_ie; + + BEGIN_BF_DECL(ip_t, uint32_t); + BF_FIELD(txwm, 0, 1); + BF_FIELD(rxwm, 1, 1); + END_BF_DECL() r_ip; + + BEGIN_BF_DECL(div_t, uint32_t); + BF_FIELD(div, 0, 16); + END_BF_DECL() r_div; + + // register declarations + sysc::sc_register txdata; + sysc::sc_register rxdata; + sysc::sc_register txctrl; + sysc::sc_register rxctrl; + sysc::sc_register ie; + sysc::sc_register ip; + sysc::sc_register div; + +public: + uart_regs(sc_core::sc_module_name nm); + + template + void registerResources(sysc::tlm_target& target); +}; +} +////////////////////////////////////////////////////////////////////////////// +// member functions +////////////////////////////////////////////////////////////////////////////// + +inline sysc::uart_regs::uart_regs(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, NAMED(txdata, r_txdata, 0, *this) +, NAMED(rxdata, r_rxdata, 0, *this) +, NAMED(txctrl, r_txctrl, 0, *this) +, NAMED(rxctrl, r_rxctrl, 0, *this) +, NAMED(ie, r_ie, 0, *this) +, NAMED(ip, r_ip, 0, *this) +, NAMED(div, r_div, 0, *this) +{ +} + +template +inline void sysc::uart_regs::registerResources(sysc::tlm_target& target) { + target.addResource(txdata, 0x0UL); + target.addResource(rxdata, 0x4UL); + target.addResource(txctrl, 0x8UL); + target.addResource(rxctrl, 0xcUL); + target.addResource(ie, 0x10UL); + target.addResource(ip, 0x14UL); + target.addResource(div, 0x18UL); +} + +#endif // _UART_REGS_H_ diff --git a/riscv/incl/sysc/SiFive/gpio.h b/riscv/incl/sysc/SiFive/gpio.h new file mode 100644 index 0000000..47e4644 --- /dev/null +++ b/riscv/incl/sysc/SiFive/gpio.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2017 eyck@minres.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ******************************************************************************/ + +#ifndef _GPIO_H_ +#define _GPIO_H_ + +#include + +namespace sysc { + +class gpio_regs; + +class gpio: public sc_core::sc_module, public tlm_target<> { +public: + SC_HAS_PROCESS(gpio); + sc_core::sc_in clk_i; + sc_core::sc_in rst_i; + gpio(sc_core::sc_module_name nm); + virtual ~gpio(); +protected: + void clock_cb(); + void reset_cb(); + sc_core::sc_time clk; + std::unique_ptr regs; +}; + +} /* namespace sysc */ + +#endif /* _GPIO_H_ */ diff --git a/riscv/incl/sysc/SiFive/platform.h b/riscv/incl/sysc/SiFive/platform.h new file mode 100644 index 0000000..5bf3d46 --- /dev/null +++ b/riscv/incl/sysc/SiFive/platform.h @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright 2017 eyck@minres.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ******************************************************************************/ +/* + * simplesystem.h + * + * Created on: 17.09.2017 + * Author: eyck@minres.com + */ + +#ifndef SIMPLESYSTEM_H_ +#define SIMPLESYSTEM_H_ + +#include "uart.h" +#include "spi.h" +#include "gpio.h" +#include "plic.h" + +#include +#include +#include + +#include "core_complex.h" + + +namespace sysc { + +class platform: public sc_core::sc_module { +public: + SC_HAS_PROCESS(platform); + + SiFive::core_complex i_master; + router<> i_router; + uart i_uart; + spi i_spi; + gpio i_gpio; + plic i_plic; + sc_core::sc_signal s_clk; + sc_core::sc_signal s_rst; + + platform(sc_core::sc_module_name nm); +protected: + void gen_reset(); + +#include "gen/e300_plat_t.h" +}; + +} /* namespace sysc */ + +#endif /* SIMPLESYSTEM_H_ */ diff --git a/riscv/incl/sysc/SiFive/plic.h b/riscv/incl/sysc/SiFive/plic.h new file mode 100644 index 0000000..3ad1e5b --- /dev/null +++ b/riscv/incl/sysc/SiFive/plic.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2017 eyck@minres.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ******************************************************************************/ + +#ifndef _PLIC_H_ +#define _PLIC_H_ + +#include + +namespace sysc { + +class plic_regs; + +class plic: public sc_core::sc_module, public tlm_target<> { +public: + SC_HAS_PROCESS(plic); + sc_core::sc_in clk_i; + sc_core::sc_in rst_i; + plic(sc_core::sc_module_name nm); + virtual ~plic(); +protected: + void clock_cb(); + void reset_cb(); + sc_core::sc_time clk; + std::unique_ptr regs; +}; + +} /* namespace sysc */ + +#endif /* _PLIC_H_ */ diff --git a/riscv/incl/sysc/SiFive/spi.h b/riscv/incl/sysc/SiFive/spi.h new file mode 100644 index 0000000..9fcea1a --- /dev/null +++ b/riscv/incl/sysc/SiFive/spi.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2017 eyck@minres.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ******************************************************************************/ + +#ifndef _SPI_H_ +#define _SPI_H_ + +#include + +namespace sysc { + +class spi_regs; + +class spi: public sc_core::sc_module, public tlm_target<> { +public: + SC_HAS_PROCESS(spi); + sc_core::sc_in clk_i; + sc_core::sc_in rst_i; + spi(sc_core::sc_module_name nm); + virtual ~spi(); +protected: + void clock_cb(); + void reset_cb(); + sc_core::sc_time clk; + std::unique_ptr regs; +}; + +} /* namespace sysc */ + +#endif /* _SPI_H_ */ diff --git a/riscv/incl/sysc/SiFive/uart.h b/riscv/incl/sysc/SiFive/uart.h new file mode 100644 index 0000000..4dc733e --- /dev/null +++ b/riscv/incl/sysc/SiFive/uart.h @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright 2017 eyck@minres.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ******************************************************************************/ + +#ifndef _UART_H_ +#define _UART_H_ + +#include + +namespace sysc { + +class uart_regs; + +class uart: public sc_core::sc_module, public tlm_target<> { +public: + SC_HAS_PROCESS(uart); + sc_core::sc_in clk_i; + sc_core::sc_in rst_i; + uart(sc_core::sc_module_name nm); + virtual ~uart(); +protected: + void clock_cb(); + void reset_cb(); + sc_core::sc_time clk; + std::unique_ptr regs; +}; + +} /* namespace sysc */ + +#endif /* _UART_H_ */ diff --git a/riscv/plic.rdl b/riscv/plic.rdl new file mode 100644 index 0000000..67c05ea --- /dev/null +++ b/riscv/plic.rdl @@ -0,0 +1,37 @@ +regfile plic_regs { + reg { + name="priority"; + desc="interrupt source priority"; + field { + name = "priority"; + } priority[2:0]; + } priority[255] @0x004; + reg { + name="pending"; + desc="pending irq"; + field { + name = "pending"; + } pending[31:0]; + } pending @0x1000; + reg { + name="enabled"; + desc="enabled interrupts"; + field { + name = "enabled"; + } enabled[31:0]; + } enabled @0x2000; + reg { + name="threshold"; + desc="interrupt priority threshold"; + field { + name = "threshold"; + } \threshold[2:0]; + } \threshold @0x0C200000; + reg { + name="claim/complete"; + desc="interrupt handling completed"; + field { + name = "interrupt_claimed"; + } interrupt_claimed[31:0]; + } claim_complete @0x0C200004; +}; \ No newline at end of file diff --git a/riscv/src/CMakeLists.txt b/riscv/src/CMakeLists.txt index a3e5dff..e373cc2 100644 --- a/riscv/src/CMakeLists.txt +++ b/riscv/src/CMakeLists.txt @@ -3,12 +3,21 @@ FILE(GLOB RiscVHeaders *.h) set(LIB_HEADERS ${RiscVHeaders} ) set(LIB_SOURCES iss/rv32imac.cpp + iss/rv64ia.cpp internal/vm_rv32imac.cpp + internal/vm_rv64ia.cpp + sysc/core_complex.cpp + sysc/gpio.cpp + sysc/plic.cpp + sysc/platform.cpp + sysc/spi.cpp + sysc/uart.cpp ) set(APP_HEADERS ) -set(APP_SOURCES main.cpp) +set(APP_SOURCES main.cpp sc_main.cpp +) # Define two variables in order not to repeat ourselves. set(LIBRARY_NAME riscv) @@ -33,10 +42,10 @@ target_link_libraries(${APPLICATION_NAME} dbt-core) target_link_libraries(${APPLICATION_NAME} sc-components) target_link_libraries(${APPLICATION_NAME} external) target_link_libraries(${APPLICATION_NAME} ${llvm_libs}) -#target_link_libraries(${APPLICATION_NAME} ${SystemC_LIBRARIES} ) -#if(SCV_FOUND) - #target_link_libraries (${APPLICATION_NAME} ${SCV_LIBRARIES}) -#endif(SCV_FOUND) +target_link_libraries(${APPLICATION_NAME} ${SystemC_LIBRARIES} ) +if(SCV_FOUND) + target_link_libraries (${APPLICATION_NAME} ${SCV_LIBRARIES}) +endif() target_link_libraries(${APPLICATION_NAME} ${Boost_LIBRARIES} ) # Says how and where to install software diff --git a/riscv/src/internal/vm_riscv.in.cpp b/riscv/src/internal/vm_riscv.in.cpp index cdebaea..b5c7b7c 100644 --- a/riscv/src/internal/vm_riscv.in.cpp +++ b/riscv/src/internal/vm_riscv.in.cpp @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include @@ -45,7 +45,7 @@ #include "iss/debugger/server.h" #include -#include "../../incl/iss/arch/riscv_hart_msu_vp.h" +#include "iss/arch/riscv_hart_msu_vp.h" namespace iss { namespace CORE_DEF_NAME { @@ -225,6 +225,17 @@ protected: ptrType); } + inline + llvm::Value* gen_reg_load(unsigned i, unsigned level=0){ +// if(level){ + return this->builder->CreateLoad(get_reg_ptr(i), false); +// } else { +// if(!this->loaded_regs[i]) +// this->loaded_regs[i]=this->builder->CreateLoad(get_reg_ptr(i), false); +// return this->loaded_regs[i]; +// } + } + inline void gen_set_pc(virt_addr_t pc){ llvm::Value* pc_l = this->builder->CreateSExt(this->gen_const(traits::caddr_bit_width, (unsigned)pc), this->get_type(traits::caddr_bit_width)); @@ -393,7 +404,7 @@ void vm_impl::gen_leave_behavior(llvm::BasicBlock* leave_blk){ template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause){ - auto* TRAP_val = this->gen_const(traits::XLEN, 0x80<<24| (cause<<16) | trap_id ); + 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); } @@ -510,7 +521,7 @@ namespace CORE_DEF_NAME { template status target_adapter::read_registers(std::vector& data, std::vector& avail) { - LOG(TRACE)<<"reading target registers"; + LOG(logging::TRACE)<<"reading target registers"; //return idx<0?:; data.clear(); avail.clear(); @@ -652,8 +663,8 @@ namespace CORE_DEF_NAME { auto saddr=map_addr({iss::CODE, iss::PHYSICAL, addr}); auto eaddr=map_addr({iss::CODE, iss::PHYSICAL, addr+length}); target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val-saddr.val); - LOG(TRACE)<<"Adding breakpoint with handle "< #include -#include +#include #include #include @@ -45,7 +45,7 @@ #include "iss/debugger/server.h" #include -#include "../../incl/iss/arch/riscv_hart_msu_vp.h" +#include "iss/arch/riscv_hart_msu_vp.h" namespace iss { namespace rv32imac { @@ -225,6 +225,17 @@ protected: ptrType); } + inline + llvm::Value* gen_reg_load(unsigned i, unsigned level=0){ + if(level){ + return this->builder->CreateLoad(get_reg_ptr(i), false); + } else { + if(!this->loaded_regs[i]) + this->loaded_regs[i]=this->builder->CreateLoad(get_reg_ptr(i), false); + return this->loaded_regs[i]; + } + } + inline void gen_set_pc(virt_addr_t pc){ llvm::Value* pc_l = this->builder->CreateSExt(this->gen_const(traits::caddr_bit_width, (unsigned)pc), this->get_type(traits::caddr_bit_width)); @@ -504,15 +515,6 @@ private: std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LUI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -546,15 +548,6 @@ private: std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AUIPC"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -575,7 +568,7 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -590,15 +583,6 @@ private: std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("JAL"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -619,12 +603,12 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } Value* PC_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -636,15 +620,6 @@ private: std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("JALR"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -666,12 +641,12 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } Value* ret_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); Value* PC_val = this->builder->CreateAnd( ret_val, @@ -686,15 +661,6 @@ private: std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BEQ"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); @@ -717,13 +683,13 @@ private: Value* PC_val = this->gen_choose( this->builder->CreateICmp( ICmpInst::ICMP_EQ, - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)), + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); @@ -736,15 +702,6 @@ private: std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BNE"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); @@ -767,13 +724,13 @@ private: Value* PC_val = this->gen_choose( this->builder->CreateICmp( ICmpInst::ICMP_NE, - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)), + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); @@ -786,15 +743,6 @@ private: std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BLT"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); @@ -818,16 +766,16 @@ private: this->builder->CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 32, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 32, true)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); @@ -840,15 +788,6 @@ private: std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BGE"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); @@ -872,16 +811,16 @@ private: this->builder->CreateICmp( ICmpInst::ICMP_SGE, this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 32, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 32, true)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); @@ -894,15 +833,6 @@ private: std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BLTU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); @@ -925,13 +855,13 @@ private: Value* PC_val = this->gen_choose( this->builder->CreateICmp( ICmpInst::ICMP_ULT, - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)), + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); @@ -944,15 +874,6 @@ private: std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BGEU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); @@ -975,13 +896,13 @@ private: Value* PC_val = this->gen_choose( this->builder->CreateICmp( ICmpInst::ICMP_UGE, - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)), + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); @@ -994,15 +915,6 @@ private: std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LB"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1023,7 +935,7 @@ private: pc=pc+4; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ Value* X_rd_val = this->gen_ext( @@ -1043,15 +955,6 @@ private: std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LH"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1072,7 +975,7 @@ private: pc=pc+4; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ Value* X_rd_val = this->gen_ext( @@ -1092,15 +995,6 @@ private: std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LW"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1121,7 +1015,7 @@ private: pc=pc+4; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ Value* X_rd_val = this->gen_ext( @@ -1141,15 +1035,6 @@ private: std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LBU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1170,7 +1055,7 @@ private: pc=pc+4; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ Value* X_rd_val = this->gen_ext( @@ -1190,15 +1075,6 @@ private: std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LHU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1219,7 +1095,7 @@ private: pc=pc+4; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ Value* X_rd_val = this->gen_ext( @@ -1239,15 +1115,6 @@ private: std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SB"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,5>(instr)) | (signed_bit_sub<25,7>(instr) << 5); @@ -1268,9 +1135,9 @@ private: pc=pc+4; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); - Value* MEM_offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false); + Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, @@ -1286,15 +1153,6 @@ private: std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SH"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,5>(instr)) | (signed_bit_sub<25,7>(instr) << 5); @@ -1315,9 +1173,9 @@ private: pc=pc+4; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); - Value* MEM_offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false); + Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, @@ -1333,15 +1191,6 @@ private: std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SW"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<7,5>(instr)) | (signed_bit_sub<25,7>(instr) << 5); @@ -1362,9 +1211,9 @@ private: pc=pc+4; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); - Value* MEM_offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false); + Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, @@ -1380,15 +1229,6 @@ private: std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ADDI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1410,7 +1250,7 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -1425,15 +1265,6 @@ private: std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLTI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1458,7 +1289,7 @@ private: this->builder->CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 32, true), this->gen_ext( this->gen_const(32U, fld_imm_val), @@ -1479,15 +1310,6 @@ private: std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLTIU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1513,7 +1335,7 @@ private: this->builder->CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 32, false), this->gen_ext( full_imm_val, @@ -1534,15 +1356,6 @@ private: std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("XORI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1564,7 +1377,7 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateXor( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -1579,15 +1392,6 @@ private: std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ORI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1609,7 +1413,7 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateOr( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -1624,15 +1428,6 @@ private: std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ANDI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1654,7 +1449,7 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAnd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -1669,15 +1464,6 @@ private: std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLLI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1699,7 +1485,7 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateShl( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_shamt_val)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -1714,15 +1500,6 @@ private: std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRLI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1744,7 +1521,7 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateLShr( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_shamt_val)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -1759,15 +1536,6 @@ private: std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRAI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1789,7 +1557,7 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAShr( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_shamt_val)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -1804,15 +1572,6 @@ private: std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ADD"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1834,8 +1593,8 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -1849,15 +1608,6 @@ private: std::tuple __sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SUB"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1879,8 +1629,8 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateSub( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -1894,15 +1644,6 @@ private: std::tuple __sll(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLL"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1924,9 +1665,9 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateShl( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->builder->CreateAnd( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 31)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -1941,15 +1682,6 @@ private: std::tuple __slt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLT"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -1974,10 +1706,10 @@ private: this->builder->CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 32, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 32, true)), this->gen_const(32U, 1), this->gen_const(32U, 0), @@ -1995,15 +1727,6 @@ private: std::tuple __sltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLTU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2028,11 +1751,11 @@ private: this->builder->CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 32, false), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 32, false)), this->gen_const(32U, 1), @@ -2051,15 +1774,6 @@ private: std::tuple __xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("XOR"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2081,8 +1795,8 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateXor( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -2096,15 +1810,6 @@ private: std::tuple __srl(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRL"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2126,9 +1831,9 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateLShr( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->builder->CreateAnd( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 31)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -2143,15 +1848,6 @@ private: std::tuple __sra(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRA"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2173,9 +1869,9 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAShr( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->builder->CreateAnd( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 31)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } @@ -2190,15 +1886,6 @@ private: std::tuple __or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("OR"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2220,8 +1907,8 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateOr( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -2235,15 +1922,6 @@ private: std::tuple __and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AND"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2265,8 +1943,8 @@ private: if(fld_rd_val != 0){ Value* X_rd_val = this->builder->CreateAnd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } this->gen_set_pc(pc, traits::NEXT_PC); @@ -2280,15 +1958,6 @@ private: std::tuple __fence(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("FENCE"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2328,15 +1997,6 @@ private: std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("FENCE_I"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2370,15 +2030,6 @@ private: std::tuple __ecall(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ECALL"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); ; @@ -2405,15 +2056,6 @@ private: std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("EBREAK"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); ; @@ -2440,15 +2082,6 @@ private: std::tuple __uret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("URET"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); ; @@ -2475,15 +2108,6 @@ private: std::tuple __sret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRET"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); ; @@ -2510,15 +2134,6 @@ private: std::tuple __mret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MRET"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); ; @@ -2545,15 +2160,6 @@ private: std::tuple __wfi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("WFI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); ; @@ -2582,15 +2188,6 @@ private: std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SFENCE.VMA"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); @@ -2629,15 +2226,6 @@ private: std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRW"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2657,7 +2245,7 @@ private: } pc=pc+4; - Value* rs_val_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* rs_val_val = this->gen_reg_load(fld_rs1_val, 0); if(fld_rd_val != 0){ Value* csr_val_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); Value* CSR_csr_val = rs_val_val; @@ -2685,15 +2273,6 @@ private: std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRS"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2714,7 +2293,7 @@ private: pc=pc+4; Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); - Value* xrs1_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* xrs1_val = this->gen_reg_load(fld_rs1_val, 0); if(fld_rd_val != 0){ Value* X_rd_val = xrd_val; this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); @@ -2739,15 +2318,6 @@ private: std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRC"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2768,7 +2338,7 @@ private: pc=pc+4; Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); - Value* xrs1_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* xrs1_val = this->gen_reg_load(fld_rs1_val, 0); if(fld_rd_val != 0){ Value* X_rd_val = xrd_val; this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); @@ -2793,15 +2363,6 @@ private: std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRWI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2844,15 +2405,6 @@ private: std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRSI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2900,15 +2452,6 @@ private: std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRCI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2956,15 +2499,6 @@ private: std::tuple __mul(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MUL"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -2987,11 +2521,11 @@ private: if(fld_rd_val != 0){ Value* res_val = this->builder->CreateMul( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 64, false), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 64, false)); Value* X_rd_val = this->gen_ext( @@ -3011,15 +2545,6 @@ private: std::tuple __mulh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MULH"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3042,11 +2567,11 @@ private: if(fld_rd_val != 0){ Value* res_val = this->builder->CreateMul( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 64, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 64, true)); Value* X_rd_val = this->gen_ext( @@ -3068,15 +2593,6 @@ private: std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MULHSU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3099,11 +2615,11 @@ private: if(fld_rd_val != 0){ Value* res_val = this->builder->CreateMul( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 64, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 64, false)); Value* X_rd_val = this->gen_ext( @@ -3125,15 +2641,6 @@ private: std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MULHU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3156,11 +2663,11 @@ private: if(fld_rd_val != 0){ Value* res_val = this->builder->CreateMul( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), 64, false), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 64, false)); Value* X_rd_val = this->gen_ext( @@ -3182,15 +2689,6 @@ private: std::tuple __div(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("DIV"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3217,7 +2715,7 @@ private: // this->builder->SetInsertPoint(bb); this->gen_cond_branch(this->builder->CreateICmp( ICmpInst::ICMP_NE, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -3225,11 +2723,11 @@ private: { Value* X_rd_val = this->builder->CreateSDiv( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 1), 32, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 1), 32, true)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); @@ -3255,15 +2753,6 @@ private: std::tuple __divu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("DIVU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3290,7 +2779,7 @@ private: // this->builder->SetInsertPoint(bb); this->gen_cond_branch(this->builder->CreateICmp( ICmpInst::ICMP_NE, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -3298,11 +2787,11 @@ private: { Value* X_rd_val = this->builder->CreateUDiv( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 1), 32, false), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 1), 32, false)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); @@ -3328,15 +2817,6 @@ private: std::tuple __rem(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("REM"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3363,7 +2843,7 @@ private: // this->builder->SetInsertPoint(bb); this->gen_cond_branch(this->builder->CreateICmp( ICmpInst::ICMP_NE, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -3371,11 +2851,11 @@ private: { Value* X_rd_val = this->builder->CreateSRem( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 1), 32, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 1), 32, true)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); @@ -3383,7 +2863,7 @@ private: this->builder->CreateBr(bbnext); this->builder->SetInsertPoint(bb_else); { - Value* X_rd_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* X_rd_val = this->gen_reg_load(fld_rs1_val, 1); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } this->builder->CreateBr(bbnext); @@ -3401,15 +2881,6 @@ private: std::tuple __remu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("REMU"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3436,7 +2907,7 @@ private: // this->builder->SetInsertPoint(bb); this->gen_cond_branch(this->builder->CreateICmp( ICmpInst::ICMP_NE, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -3444,11 +2915,11 @@ private: { Value* X_rd_val = this->builder->CreateURem( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 1), 32, false), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 1), 32, false)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); @@ -3456,7 +2927,7 @@ private: this->builder->CreateBr(bbnext); this->builder->SetInsertPoint(bb_else); { - Value* X_rd_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* X_rd_val = this->gen_reg_load(fld_rs1_val, 1); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } this->builder->CreateBr(bbnext); @@ -3474,15 +2945,6 @@ private: std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LR.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3504,7 +2966,7 @@ private: pc=pc+4; if(fld_rd_val != 0){ - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* X_rd_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -3530,15 +2992,6 @@ private: std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SC.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3560,7 +3013,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); @@ -3573,7 +3026,7 @@ private: bbnext); this->builder->SetInsertPoint(bb_then); { - Value* MEM_offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false); + Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 1); this->gen_write_mem( traits::MEM, offs_val, @@ -3604,15 +3057,6 @@ private: std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOSWAP.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3634,7 +3078,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); if(fld_rd_val != 0){ Value* X_rd_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), @@ -3642,7 +3086,7 @@ private: true); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } - Value* MEM_offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false); + Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, @@ -3658,15 +3102,6 @@ private: std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOADD.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3688,7 +3123,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -3699,7 +3134,7 @@ private: } Value* res2_val = this->builder->CreateAdd( res1_val, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, @@ -3716,15 +3151,6 @@ private: std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOXOR.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3746,7 +3172,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -3757,7 +3183,7 @@ private: } Value* res2_val = this->builder->CreateXor( res1_val, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, @@ -3774,15 +3200,6 @@ private: std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOAND.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3804,7 +3221,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -3815,7 +3232,7 @@ private: } Value* res2_val = this->builder->CreateAnd( res1_val, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, @@ -3832,15 +3249,6 @@ private: std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOOR.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3862,7 +3270,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -3873,7 +3281,7 @@ private: } Value* res2_val = this->builder->CreateOr( res1_val, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, @@ -3890,15 +3298,6 @@ private: std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOMIN.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3920,7 +3319,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -3936,9 +3335,9 @@ private: res1_val, 32, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 32, true)), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), res1_val, 32); Value* MEM_offs_val = res2_val; @@ -3957,15 +3356,6 @@ private: std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOMAX.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -3987,7 +3377,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -4003,9 +3393,9 @@ private: res1_val, 32, true), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 32, true)), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), res1_val, 32); Value* MEM_offs_val = res2_val; @@ -4024,15 +3414,6 @@ private: std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOMINU.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -4054,7 +3435,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -4067,8 +3448,8 @@ private: this->builder->CreateICmp( ICmpInst::ICMP_UGT, res1_val, - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0)), + this->gen_reg_load(fld_rs2_val, 0), res1_val, 32); Value* MEM_offs_val = res2_val; @@ -4087,15 +3468,6 @@ private: std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AMOMAXU.W"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); @@ -4117,7 +3489,7 @@ private: } pc=pc+4; - Value* offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, @@ -4133,9 +3505,9 @@ private: res1_val, 32, false), this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), 32, false)), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false), + this->gen_reg_load(fld_rs2_val, 0), res1_val, 32); Value* MEM_offs_val = res2_val; @@ -4154,15 +3526,6 @@ private: std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.ADDI4SPN"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr)); @@ -4187,7 +3550,7 @@ private: uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t x2_idx_val = 2; Value* X_rd_idx_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(x2_idx_val), false), + this->gen_reg_load(x2_idx_val, 0), this->gen_const(32U, fld_nzuimm_val)); this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); this->gen_set_pc(pc, traits::NEXT_PC); @@ -4201,15 +3564,6 @@ private: std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.LW"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr)); @@ -4231,7 +3585,7 @@ private: uint8_t rs1_idx_val = (fld_rs1_val + 8); Value* adr_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(rs1_idx_val), false), + this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_uimm_val)); uint8_t rd_idx_val = (fld_rd_val + 8); Value* X_rd_idx_val = this->gen_read_mem(traits::MEM, adr_val, 32/8); @@ -4247,15 +3601,6 @@ private: std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.SW"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); @@ -4277,10 +3622,10 @@ private: uint8_t rs1_idx_val = (fld_rs1_val + 8); Value* adr_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(rs1_idx_val), false), + this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_uimm_val)); uint8_t rs2_idx_val = (fld_rs2_val + 8); - Value* MEM_adr_val = this->builder->CreateLoad(get_reg_ptr(rs2_idx_val), false); + Value* MEM_adr_val = this->gen_reg_load(rs2_idx_val, 0); this->gen_write_mem( traits::MEM, adr_val, @@ -4296,15 +3641,6 @@ private: std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.NOP"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); ; @@ -4334,15 +3670,6 @@ private: std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.ADDI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int8_t fld_nzimm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); @@ -4365,7 +3692,7 @@ private: this->gen_raise_trap(0, 2); } Value* X_rs1_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_nzimm_val)); this->builder->CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false); this->gen_set_pc(pc, traits::NEXT_PC); @@ -4379,15 +3706,6 @@ private: std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.JAL"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 11); @@ -4407,11 +3725,11 @@ private: uint8_t rd_val = 1; Value* X_rd_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 2)); this->builder->CreateStore(X_rd_val, get_reg_ptr(rd_val), false); Value* PC_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -4423,15 +3741,6 @@ private: std::tuple __c_li(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.LI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); @@ -4466,15 +3775,6 @@ private: std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.LUI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int32_t fld_nzimm_val = 0 | (bit_sub<2,5>(instr) << 12) | (signed_bit_sub<12,1>(instr) << 17); @@ -4515,15 +3815,6 @@ private: std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.ADDI16SP"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_nzimm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 9); @@ -4544,7 +3835,7 @@ private: uint8_t x2_idx_val = 2; Value* X_x2_idx_val = this->builder->CreateAdd( this->gen_ext( - this->builder->CreateLoad(get_reg_ptr(x2_idx_val), false), + this->gen_reg_load(x2_idx_val, 0), 32, true), this->gen_const(32U, fld_nzimm_val)); this->builder->CreateStore(X_x2_idx_val, get_reg_ptr(x2_idx_val), false); @@ -4559,15 +3850,6 @@ private: std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.SRLI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5); @@ -4591,7 +3873,7 @@ private: } uint8_t rs1_idx_val = (fld_rs1_val + 8); Value* X_rs1_idx_val = this->builder->CreateLShr( - this->builder->CreateLoad(get_reg_ptr(rs1_idx_val), false), + this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_shamt_val)); this->builder->CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_val), false); this->gen_set_pc(pc, traits::NEXT_PC); @@ -4605,15 +3887,6 @@ private: std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.SRAI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5); @@ -4637,7 +3910,7 @@ private: } uint8_t rs1_idx_val = (fld_rs1_val + 8); Value* X_rs1_idx_val = this->builder->CreateAShr( - this->builder->CreateLoad(get_reg_ptr(rs1_idx_val), false), + this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_shamt_val)); this->builder->CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_val), false); this->gen_set_pc(pc, traits::NEXT_PC); @@ -4651,15 +3924,6 @@ private: std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.ANDI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); @@ -4680,7 +3944,7 @@ private: uint8_t rs1_idx_val = (fld_rs1_val + 8); Value* X_rs1_idx_val = this->builder->CreateAnd( - this->builder->CreateLoad(get_reg_ptr(rs1_idx_val), false), + this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_val), false); this->gen_set_pc(pc, traits::NEXT_PC); @@ -4694,15 +3958,6 @@ private: std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.SUB"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); @@ -4724,8 +3979,8 @@ private: uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); Value* X_rd_idx_val = this->builder->CreateSub( - this->builder->CreateLoad(get_reg_ptr(rd_idx_val), false), - this->builder->CreateLoad(get_reg_ptr(rs2_idx_val), false)); + this->gen_reg_load(rd_idx_val, 0), + this->gen_reg_load(rs2_idx_val, 0)); this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -4738,15 +3993,6 @@ private: std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.XOR"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); @@ -4768,8 +4014,8 @@ private: uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); Value* X_rd_idx_val = this->builder->CreateXor( - this->builder->CreateLoad(get_reg_ptr(rd_idx_val), false), - this->builder->CreateLoad(get_reg_ptr(rs2_idx_val), false)); + this->gen_reg_load(rd_idx_val, 0), + this->gen_reg_load(rs2_idx_val, 0)); this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -4782,15 +4028,6 @@ private: std::tuple __c_or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.OR"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); @@ -4812,8 +4049,8 @@ private: uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); Value* X_rd_idx_val = this->builder->CreateOr( - this->builder->CreateLoad(get_reg_ptr(rd_idx_val), false), - this->builder->CreateLoad(get_reg_ptr(rs2_idx_val), false)); + this->gen_reg_load(rd_idx_val, 0), + this->gen_reg_load(rs2_idx_val, 0)); this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -4826,15 +4063,6 @@ private: std::tuple __c_and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.AND"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); @@ -4856,8 +4084,8 @@ private: uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); Value* X_rd_idx_val = this->builder->CreateAnd( - this->builder->CreateLoad(get_reg_ptr(rd_idx_val), false), - this->builder->CreateLoad(get_reg_ptr(rs2_idx_val), false)); + this->gen_reg_load(rd_idx_val, 0), + this->gen_reg_load(rs2_idx_val, 0)); this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -4870,15 +4098,6 @@ private: std::tuple __c_j(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.J"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 11); @@ -4897,7 +4116,7 @@ private: pc=pc+2; Value* PC_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -4909,15 +4128,6 @@ private: std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.BEQZ"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8); @@ -4940,13 +4150,13 @@ private: Value* PC_val = this->gen_choose( this->builder->CreateICmp( ICmpInst::ICMP_EQ, - this->builder->CreateLoad(get_reg_ptr(rs1_val), false), + this->gen_reg_load(rs1_val, 0), this->gen_const(32U, 0)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 2)), 32); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); @@ -4959,15 +4169,6 @@ private: std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.BNEZ"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8); @@ -4990,13 +4191,13 @@ private: Value* PC_val = this->gen_choose( this->builder->CreateICmp( ICmpInst::ICMP_NE, - this->builder->CreateLoad(get_reg_ptr(rs1_val), false), + this->gen_reg_load(rs1_val, 0), this->gen_const(32U, 0)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 2)), 32); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); @@ -5009,15 +4210,6 @@ private: std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.SLLI"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5); @@ -5043,7 +4235,7 @@ private: this->gen_raise_trap(0, 2); } Value* X_rs1_val = this->builder->CreateShl( - this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false), + this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_shamt_val)); this->builder->CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false); this->gen_set_pc(pc, traits::NEXT_PC); @@ -5057,15 +4249,6 @@ private: std::tuple __c_lqsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.LQSP"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint16_t fld_uimm_val = 0 | (bit_sub<2,4>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 5); @@ -5095,15 +4278,6 @@ private: std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.LWSP"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_uimm_val = 0 | (bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5); @@ -5124,7 +4298,7 @@ private: uint8_t x2_idx_val = 2; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(x2_idx_val), false), + this->gen_reg_load(x2_idx_val, 0), this->gen_const(32U, fld_uimm_val)); Value* X_rd_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); @@ -5139,15 +4313,6 @@ private: std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.MV"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); @@ -5166,7 +4331,7 @@ private: } pc=pc+2; - Value* X_rd_val = this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false); + Value* X_rd_val = this->gen_reg_load(fld_rs2_val, 0); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -5179,15 +4344,6 @@ private: std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.JR"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); @@ -5205,7 +4361,7 @@ private: } pc=pc+2; - Value* PC_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* PC_val = this->gen_reg_load(fld_rs1_val, 0); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ this->gen_trap_check(this->leave_blk); @@ -5216,15 +4372,6 @@ private: std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.EBREAK"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); ; @@ -5251,15 +4398,6 @@ private: std::tuple __c_add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.ADD"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); @@ -5279,8 +4417,8 @@ private: pc=pc+2; Value* X_rd_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(fld_rd_val), false), - this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false)); + this->gen_reg_load(fld_rd_val, 0), + this->gen_reg_load(fld_rs2_val, 0)); this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -5293,15 +4431,6 @@ private: std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.JALR"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); @@ -5321,10 +4450,10 @@ private: uint8_t rd_val = 1; Value* X_rd_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::PC), false), + this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 2)); this->builder->CreateStore(X_rd_val, get_reg_ptr(rd_val), false); - Value* PC_val = this->builder->CreateLoad(get_reg_ptr(fld_rs1_val), false); + Value* PC_val = this->gen_reg_load(fld_rs1_val, 0); this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ this->gen_trap_check(this->leave_blk); @@ -5335,15 +4464,6 @@ private: std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("C.SWSP"); - this->gen_set_pc(pc, traits::PC); - this->builder->CreateStore( - this->builder->CreateLoad(get_reg_ptr(traits::PENDING_TRAP), true), - get_reg_ptr(traits::TRAP_STATE), true); - this->builder->CreateStore( - this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), false), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), false); this->gen_sync(iss::PRE_SYNC); uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); @@ -5364,9 +4484,9 @@ private: uint8_t x2_idx_val = 2; Value* offs_val = this->builder->CreateAdd( - this->builder->CreateLoad(get_reg_ptr(x2_idx_val), false), + this->gen_reg_load(x2_idx_val, 0), this->gen_const(32U, fld_uimm_val)); - Value* MEM_offs_val = this->builder->CreateLoad(get_reg_ptr(fld_rs2_val), false); + Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, @@ -5588,7 +4708,7 @@ namespace rv32imac { template status target_adapter::read_registers(std::vector& data, std::vector& avail) { - LOG(TRACE)<<"reading target registers"; + LOG(logging::TRACE)<<"reading target registers"; //return idx<0?:; data.clear(); avail.clear(); @@ -5730,8 +4850,8 @@ namespace rv32imac { auto saddr=map_addr({iss::CODE, iss::PHYSICAL, addr}); auto eaddr=map_addr({iss::CODE, iss::PHYSICAL, addr+length}); target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val-saddr.val); - LOG(TRACE)<<"Adding breakpoint with handle "< +#include #include #include diff --git a/riscv/src/main.cpp b/riscv/src/main.cpp index 75a5910..60da773 100644 --- a/riscv/src/main.cpp +++ b/riscv/src/main.cpp @@ -38,9 +38,8 @@ #include #include -#ifndef WITHOUT_LLVM +#include #include -#endif #ifdef WITH_SYSTEMC #include #endif @@ -48,8 +47,6 @@ namespace po= boost::program_options; -INITIALIZE_EASYLOGGINGPP - int main(int argc, char *argv[]) { try{ /** Define and parse the program options @@ -63,17 +60,26 @@ int main(int argc, char *argv[]) { // application code comes here // iss::init_jit(argc, argv); if(vm.count("systemc")){ -//#ifdef WITH_SYSTEMC -// return sc_core::sc_elab_and_sim(argc, argv); -//#else +#ifdef WITH_SYSTEMC + return sc_core::sc_elab_and_sim(argc, argv); +#else std::cerr<<"SystemC simulation is currently not supported, please rebuild with -DWITH_SYSTEMC"< cpu = vm.count("gdb-port")? - iss::create("rv32ima", vm["gdb-port"].as(), dump): - iss::create("rv32ima", dump); + std::unique_ptr cpu = nullptr; + if(vm.count("rv64")==1){ + if(vm.count("gdb-port")==1) + cpu = iss::create("rv64ia", vm["gdb-port"].as(), dump); + else + cpu = iss::create("rv64ia", dump); + } else { + if(vm.count("gdb-port")==1) + cpu = iss::create("rv32ima", vm["gdb-port"].as(), dump); + else + cpu = iss::create("rv32ima", dump); + } if(vm.count("elf")){ for(std::string input: vm["elf"].as >()) cpu->get_arch()->load_file(input); @@ -96,7 +102,7 @@ int main(int argc, char *argv[]) { return cpu->start(vm["cycles"].as()); } } catch(std::exception& e){ - LOG(ERROR) << "Unhandled Exception reached the top of main: " + LOG(logging::ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl; return ERROR_UNHANDLED_EXCEPTION; } diff --git a/riscv/src/minres_rv.core_desc b/riscv/src/minres_rv.core_desc index 126bddf..a34c6f5 100644 --- a/riscv/src/minres_rv.core_desc +++ b/riscv/src/minres_rv.core_desc @@ -2,9 +2,9 @@ import "RV32IBase.core_desc" import "RV32M.core_desc" import "RV32A.core_desc" import "RV32C.core_desc" -//import "RV64IBase.core_desc" +import "RV64IBase.core_desc" //import "RV64M.core_desc" -//import "RV64A.core_desc" +import "RV64A.core_desc" Core RV32IMAC provides RV32IBase,RV32M,RV32A, RV32CI { template:"vm_riscv.in.cpp"; @@ -15,8 +15,8 @@ Core RV32IMAC provides RV32IBase,RV32M,RV32A, RV32CI { PCLEN:=32; fence:=0; fencei:=1; - fencevmal:=2; - fencevmau:=3; + fencevmal:=2; + fencevmau:=3; // XL ZYXWVUTSRQPONMLKJIHGFEDCBA MISA_VAL:=0b01000000000101000001000100000001; PGSIZE := 4096; //1 << 12; @@ -24,15 +24,21 @@ Core RV32IMAC provides RV32IBase,RV32M,RV32A, RV32CI { } } -/* -Core RV64IMA provides RV64IBase, RV64M, RV64A { + +Core RV64IA provides RV64IBase,RV64A { template:"vm_riscv.in.cpp"; constants { XLEN:=64; + XLEN2:=128; XLEN_BIT_MASK:=0x3f; PCLEN:=64; fence:=0; fencei:=1; + fencevmal:=2; + fencevmau:=3; + // XL ZYXWVUTSRQPONMLKJIHGFEDCBA + MISA_VAL:=0b10000000000001000001000100000000; + PGSIZE := 4096; //1 << 12; + PGMASK := 4095; //PGSIZE-1 } } -*/ \ No newline at end of file diff --git a/riscv/src/sc_main.cpp b/riscv/src/sc_main.cpp new file mode 100644 index 0000000..bad3bf4 --- /dev/null +++ b/riscv/src/sc_main.cpp @@ -0,0 +1,83 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 eyck@minres.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +//////////////////////////////////////////////////////////////////////////////// +/* + * sc_main.cpp + * + * Created on: 17.09.2017 + * Author: eyck@minres.com + */ + +#include +#include +#include +#include +#include +#include +#include + +using namespace sysc; +namespace po = boost::program_options; + +namespace { +const size_t ERROR_IN_COMMAND_LINE = 1; +const size_t SUCCESS = 0; +const size_t ERROR_UNHANDLED_EXCEPTION = 2; +} // namespace + +int sc_main(int argc, char* argv[]){ +// sc_report_handler::set_handler(my_report_handler); + sysc::Logger::reporting_level()=log::DEBUG; + /////////////////////////////////////////////////////////////////////////// + // CLI argument parsing + /////////////////////////////////////////////////////////////////////////// + po::options_description desc("Options");\ + desc.add_options()\ + ("help,h", "Print help message")\ + ("debug,d", po::value(), "set debug level")\ + ("trace,t", "trace SystemC signals"); + po::variables_map vm; + try { + po::store(po::parse_command_line(argc, argv, desc), vm); // can throw + // --help option + if ( vm.count("help") ){ + std::cout << "JIT-ISS simulator for AVR" << std::endl << desc << std::endl; + return SUCCESS; + } + po::notify(vm); // throws on error, so do after help in case + // there are any problems + } catch(po::error& e){ + std::cerr << "ERROR: " << e.what() << std::endl << std::endl; + std::cerr << desc << std::endl; + return ERROR_IN_COMMAND_LINE; + } + /////////////////////////////////////////////////////////////////////////// + // set up tracing & transaction recording + /////////////////////////////////////////////////////////////////////////// + sysc::tracer trace("simple_system", sysc::tracer::TEXT, vm.count("trace")); + /////////////////////////////////////////////////////////////////////////// + // instantiate top level + /////////////////////////////////////////////////////////////////////////// + platform i_simple_system("i_simple_system"); + //sr_report_handler::add_sc_object_to_filter(&i_simple_system.i_master, sc_core::SC_WARNING, sc_core::SC_MEDIUM); + + /////////////////////////////////////////////////////////////////////////// + // run simulation + /////////////////////////////////////////////////////////////////////////// + sc_start(sc_core::sc_time(100, sc_core::SC_NS)); + if(!sc_end_of_simulation_invoked()) sc_stop(); + return 0; +} + diff --git a/riscv/src/sysc/core_complex.cpp b/riscv/src/sysc/core_complex.cpp new file mode 100644 index 0000000..c1acf0d --- /dev/null +++ b/riscv/src/sysc/core_complex.cpp @@ -0,0 +1,55 @@ +//////////////////////////////////////////////////////////////////////////////// +// 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 +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include + +namespace sysc { +namespace SiFive { + +core_complex::core_complex(sc_core::sc_module_name name) +:sc_core::sc_module(name) +, NAMED(initiator) +, NAMED(rst_i){ + // TODO Auto-generated constructor stub + +} + +core_complex::~core_complex() { + // TODO Auto-generated destructor stub +} + +} /* namespace SiFive */ +} /* namespace sysc */ diff --git a/riscv/src/sysc/gpio.cpp b/riscv/src/sysc/gpio.cpp new file mode 100644 index 0000000..970e69c --- /dev/null +++ b/riscv/src/sysc/gpio.cpp @@ -0,0 +1,50 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 eyck@minres.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +//////////////////////////////////////////////////////////////////////////////// + +#include "sysc/SiFive/gpio.h" +#include "sysc/SiFive/gen/gpio_regs.h" +#include "sysc/utilities.h" + +namespace sysc { + +gpio::gpio(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, tlm_target<>(clk) +, NAMED(clk_i) +, NAMED(rst_i) +, NAMEDD(gpio_regs, regs) +{ + regs->registerResources(*this); + SC_METHOD(clock_cb); + sensitive<reset_start(); + else + regs->reset_stop(); +} + +} /* namespace sysc */ diff --git a/riscv/src/sysc/platform.cpp b/riscv/src/sysc/platform.cpp new file mode 100644 index 0000000..a18145c --- /dev/null +++ b/riscv/src/sysc/platform.cpp @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 eyck@minres.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +//////////////////////////////////////////////////////////////////////////////// +/* + * simplesystem.cpp + * + * Created on: 17.09.2017 + * Author: eyck@minres.com + */ + +#include + +namespace sysc { + +platform::platform(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, NAMED(i_master) +, NAMED(i_router, 4, 1) +, NAMED(i_uart) +, NAMED(i_spi) +, NAMED(i_gpio) +, NAMED(i_plic) +, NAMED(s_clk) +, NAMED(s_rst) +{ + i_master.initiator(i_router.target[0]); + size_t i=0; + for(const auto& e: e300_plat_map){ + i_router.initiator.at(i)(e.target->socket); + i_router.add_target_range(i, e.start, e.size); + i++; + } + i_uart.clk_i(s_clk); + i_spi.clk_i(s_clk); + i_gpio.clk_i(s_clk); + i_plic.clk_i(s_clk); + s_clk.write(10_ns); + + i_uart.rst_i(s_rst); + i_spi.rst_i(s_rst); + i_gpio.rst_i(s_rst); + i_plic.rst_i(s_rst); + i_master.rst_i(s_rst); + + SC_THREAD(gen_reset); +} + +void platform::gen_reset() { + s_rst=true; + wait(10_ns); + s_rst=false; +} + +} /* namespace sysc */ diff --git a/riscv/src/sysc/plic.cpp b/riscv/src/sysc/plic.cpp new file mode 100644 index 0000000..41f980f --- /dev/null +++ b/riscv/src/sysc/plic.cpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 eyck@minres.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +//////////////////////////////////////////////////////////////////////////////// + +#include "sysc/SiFive/plic.h" +#include "sysc/SiFive/gen/plic_regs.h" +#include "sysc/utilities.h" + +namespace sysc { + +plic::plic(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, tlm_target<>(clk) +, NAMED(clk_i) +, NAMED(rst_i) +, NAMEDD(plic_regs, regs) +{ + regs->registerResources(*this); + SC_METHOD(clock_cb); + sensitive<clk=clk_i.read(); +} + +void plic::reset_cb() { + if(rst_i.read()) + regs->reset_start(); + else + regs->reset_stop(); +} + +} /* namespace sysc */ diff --git a/riscv/src/sysc/spi.cpp b/riscv/src/sysc/spi.cpp new file mode 100644 index 0000000..d5445ac --- /dev/null +++ b/riscv/src/sysc/spi.cpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 eyck@minres.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +//////////////////////////////////////////////////////////////////////////////// + +#include "sysc/SiFive/spi.h" +#include "sysc/SiFive/gen/spi_regs.h" +#include "sysc/utilities.h" + +namespace sysc { + +spi::spi(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, tlm_target<>(clk) +, NAMED(clk_i) +, NAMED(rst_i) +, NAMEDD(spi_regs, regs) +{ + regs->registerResources(*this); + SC_METHOD(clock_cb); + sensitive<clk=clk_i.read(); +} + +void spi::reset_cb() { + if(rst_i.read()) + regs->reset_start(); + else + regs->reset_stop(); +} + +} /* namespace sysc */ diff --git a/riscv/src/sysc/uart.cpp b/riscv/src/sysc/uart.cpp new file mode 100644 index 0000000..0e5df18 --- /dev/null +++ b/riscv/src/sysc/uart.cpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 eyck@minres.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +//////////////////////////////////////////////////////////////////////////////// + +#include "sysc/SiFive/uart.h" +#include "sysc/SiFive/gen/uart_regs.h" +#include "sysc/utilities.h" + +namespace sysc { + +uart::uart(sc_core::sc_module_name nm) +: sc_core::sc_module(nm) +, tlm_target<>(clk) +, NAMED(clk_i) +, NAMED(rst_i) +, NAMEDD(uart_regs, regs) +{ + regs->registerResources(*this); + SC_METHOD(clock_cb); + sensitive<clk=clk_i.read(); +} + +void uart::reset_cb() { + if(rst_i.read()) + regs->reset_start(); + else + regs->reset_stop(); +} + +} /* namespace sysc */