diff --git a/gen_input/templates/llvm/vm-vm_CORENAME.cpp.gtl b/gen_input/templates/llvm/vm-vm_CORENAME.cpp.gtl index 881cb30..d0a8067 100644 --- a/gen_input/templates/llvm/vm-vm_CORENAME.cpp.gtl +++ b/gen_input/templates/llvm/vm-vm_CORENAME.cpp.gtl @@ -30,10 +30,10 @@ * *******************************************************************************/ -#include -#include #include #include +#include +#include #include #include #include diff --git a/src/iss/plugin/cycle_estimate.h b/src/iss/plugin/cycle_estimate.h index a8345f5..f35f106 100644 --- a/src/iss/plugin/cycle_estimate.h +++ b/src/iss/plugin/cycle_estimate.h @@ -45,7 +45,7 @@ namespace iss { namespace plugin { -class cycle_estimate: public iss::vm_plugin { +class cycle_estimate: public vm_plugin { BEGIN_BF_DECL(instr_desc, uint32_t) BF_FIELD(taken, 24, 8) BF_FIELD(not_taken, 16, 8) diff --git a/src/main.cpp b/src/main.cpp index c2b5254..2948993 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,236 +1,241 @@ -/******************************************************************************* - * Copyright (C) 2017, 2018 MINRES Technologies GmbH - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - *******************************************************************************/ - -#include -#include - -#include -#include -#include "iss/arch/tgc_mapper.h" -#ifdef WITH_LLVM -#include -#endif -#include -#include "iss/plugin/cycle_estimate.h" -#include "iss/plugin/instruction_count.h" -#include "iss/plugin/pctrace.h" -#include -#if defined(HAS_LUA) -#include -#endif - -namespace po = boost::program_options; - -int main(int argc, char *argv[]) { - /* - * Define and parse the program options - */ - po::variables_map clim; - po::options_description desc("Options"); - // clang-format off - desc.add_options() - ("help,h", "Print help message") - ("verbose,v", po::value()->implicit_value(0), "Sets logging verbosity") - ("logfile,l", po::value(), "Sets default log file.") - ("disass,d", po::value()->implicit_value(""), "Enables disassembly") - ("gdb-port,g", po::value()->default_value(0), "enable gdb server and specify port to use") - ("instructions,i", po::value()->default_value(std::numeric_limits::max()), "max. number of instructions to simulate") - ("reset,r", po::value(), "reset address") - ("dump-ir", "dump the intermediate representation") - ("elf,f", po::value>(), "ELF file(s) to load") - ("mem,m", po::value(), "the memory input file") - ("plugin,p", po::value>(), "plugin to activate") - ("backend", po::value()->default_value("interp"), "the memory input file") - ("isa", po::value()->default_value("tgc_c"), "isa to use for simulation"); - // clang-format on - auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); - try { - po::store(parsed, clim); // can throw - // --help option - if (clim.count("help")) { - std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl; - return 0; - } - po::notify(clim); // throws on error, so do after help in case - } catch (po::error &e) { - // there are problems - std::cerr << "ERROR: " << e.what() << std::endl << std::endl; - std::cerr << desc << std::endl; - return 1; - } - std::vector args = collect_unrecognized(parsed.options, po::include_positional); - - LOGGER(DEFAULT)::print_time() = false; - LOGGER(connection)::print_time() = false; - if (clim.count("verbose")) { - auto l = logging::as_log_level(clim["verbose"].as()); - LOGGER(DEFAULT)::reporting_level() = l; - LOGGER(connection)::reporting_level() = l; - } - if (clim.count("logfile")) { - // configure the connection logger - auto f = fopen(clim["logfile"].as().c_str(), "w"); - LOG_OUTPUT(DEFAULT)::stream() = f; - LOG_OUTPUT(connection)::stream() = f; - } - - std::vector plugin_list; - auto res = 0; - try { -#ifdef WITH_LLVM - // application code comes here // - iss::init_jit_debug(argc, argv); -#endif - bool dump = clim.count("dump-ir"); - // instantiate the simulator - iss::vm_ptr vm{nullptr}; - iss::cpu_ptr cpu{nullptr}; - std::string isa_opt(clim["isa"].as()); - if (isa_opt == "tgc_c") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#ifdef CORE_TGC_B - if (isa_opt == "tgc_b") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_C_XRB_NN - if (isa_opt == "tgc_c_xrb_nn") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_D - if (isa_opt == "tgc_d") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_D_XRB_MAC - if (isa_opt == "tgc_d_xrb_mac") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_D_XRB_NN - if (isa_opt == "tgc_d_xrb_nn") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_E - if (isa_opt == "tgc_e") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif - { +/******************************************************************************* + * Copyright (C) 2017, 2018 MINRES Technologies GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************/ + +#include +#include "iss/factory.h" + +#include +#include +#include "iss/arch/tgc_mapper.h" +#ifdef WITH_LLVM +#include +#endif +#include +#include "iss/plugin/cycle_estimate.h" +#include "iss/plugin/instruction_count.h" +#include "iss/plugin/pctrace.h" +#ifndef WIN32 +#include +#endif +#if defined(HAS_LUA) +#include +#endif + +namespace po = boost::program_options; + +int main(int argc, char *argv[]) { + /* + * Define and parse the program options + */ + po::variables_map clim; + po::options_description desc("Options"); + // clang-format off + desc.add_options() + ("help,h", "Print help message") + ("verbose,v", po::value()->implicit_value(0), "Sets logging verbosity") + ("logfile,l", po::value(), "Sets default log file.") + ("disass,d", po::value()->implicit_value(""), "Enables disassembly") + ("gdb-port,g", po::value()->default_value(0), "enable gdb server and specify port to use") + ("instructions,i", po::value()->default_value(std::numeric_limits::max()), "max. number of instructions to simulate") + ("reset,r", po::value(), "reset address") + ("dump-ir", "dump the intermediate representation") + ("elf,f", po::value>(), "ELF file(s) to load") + ("mem,m", po::value(), "the memory input file") + ("plugin,p", po::value>(), "plugin to activate") + ("backend", po::value()->default_value("interp"), "the memory input file") + ("isa", po::value()->default_value("tgc_c"), "isa to use for simulation"); + // clang-format on + auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); + try { + po::store(parsed, clim); // can throw + // --help option + if (clim.count("help")) { + std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl; + return 0; + } + po::notify(clim); // throws on error, so do after help in case + } catch (po::error &e) { + // there are problems + std::cerr << "ERROR: " << e.what() << std::endl << std::endl; + std::cerr << desc << std::endl; + return 1; + } + std::vector args = collect_unrecognized(parsed.options, po::include_positional); + + LOGGER(DEFAULT)::print_time() = false; + LOGGER(connection)::print_time() = false; + if (clim.count("verbose")) { + auto l = logging::as_log_level(clim["verbose"].as()); + LOGGER(DEFAULT)::reporting_level() = l; + LOGGER(connection)::reporting_level() = l; + } + if (clim.count("logfile")) { + // configure the connection logger + auto f = fopen(clim["logfile"].as().c_str(), "w"); + LOG_OUTPUT(DEFAULT)::stream() = f; + LOG_OUTPUT(connection)::stream() = f; + } + + std::vector plugin_list; + auto res = 0; + try { +#ifdef WITH_LLVM + // application code comes here // + iss::init_jit_debug(argc, argv); +#endif + bool dump = clim.count("dump-ir"); + // instantiate the simulator + iss::vm_ptr vm{nullptr}; + iss::cpu_ptr cpu{nullptr}; + std::string isa_opt(clim["isa"].as()); + if (isa_opt == "tgc_c") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#ifdef CORE_TGC_B + if (isa_opt == "tgc_b") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#endif +#ifdef CORE_TGC_C_XRB_NN + if (isa_opt == "tgc_c_xrb_nn") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#endif +#ifdef CORE_TGC_D + if (isa_opt == "tgc_d") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#endif +#ifdef CORE_TGC_D_XRB_MAC + if (isa_opt == "tgc_d_xrb_mac") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#endif +#ifdef CORE_TGC_D_XRB_NN + if (isa_opt == "tgc_d_xrb_nn") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#endif +#ifdef CORE_TGC_E + if (isa_opt == "tgc_e") { + std::tie(cpu, vm) = + iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); + } else +#endif + { LOG(ERR) << "Illegal argument value for '--isa': " << isa_opt << std::endl; - return 127; - } - if (clim.count("plugin")) { - for (std::string const& opt_val : clim["plugin"].as>()) { - std::string plugin_name=opt_val; - std::string filename{"cycles.txt"}; - std::size_t found = opt_val.find('='); - if (found != std::string::npos) { - plugin_name = opt_val.substr(0, found); - filename = opt_val.substr(found + 1, opt_val.size()); - } - if (plugin_name == "ic") { - auto *ic_plugin = new iss::plugin::instruction_count(filename); - vm->register_plugin(*ic_plugin); - plugin_list.push_back(ic_plugin); - } else if (plugin_name == "ce") { - auto *ce_plugin = new iss::plugin::cycle_estimate(filename); - vm->register_plugin(*ce_plugin); - plugin_list.push_back(ce_plugin); - } else if (plugin_name == "pctrace") { - auto *plugin = new iss::plugin::pctrace(filename); - vm->register_plugin(*plugin); - plugin_list.push_back(plugin); - } else { - std::array a{{filename.c_str()}}; - iss::plugin::loader l(plugin_name, {{"initPlugin"}}); - auto* plugin = l.call_function("initPlugin", a.size(), a.data()); - if(plugin){ - vm->register_plugin(*plugin); - plugin_list.push_back(plugin); - } else { + return 127; + } + if (clim.count("plugin")) { + for (std::string const& opt_val : clim["plugin"].as>()) { + std::string plugin_name=opt_val; + std::string filename{"cycles.txt"}; + std::size_t found = opt_val.find('='); + if (found != std::string::npos) { + plugin_name = opt_val.substr(0, found); + filename = opt_val.substr(found + 1, opt_val.size()); + } + if (plugin_name == "ic") { + auto *ic_plugin = new iss::plugin::instruction_count(filename); + vm->register_plugin(*ic_plugin); + plugin_list.push_back(ic_plugin); + } else if (plugin_name == "ce") { + auto *ce_plugin = new iss::plugin::cycle_estimate(filename); + vm->register_plugin(*ce_plugin); + plugin_list.push_back(ce_plugin); + } else if (plugin_name == "pctrace") { + auto *plugin = new iss::plugin::pctrace(filename); + vm->register_plugin(*plugin); + plugin_list.push_back(plugin); + } else { +#ifndef WIN32 + std::array a{{filename.c_str()}}; + iss::plugin::loader l(plugin_name, {{"initPlugin"}}); + auto* plugin = l.call_function("initPlugin", a.size(), a.data()); + if(plugin){ + vm->register_plugin(*plugin); + plugin_list.push_back(plugin); + } else +#endif + { LOG(ERR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl; - return 127; - } - } - } - } - if (clim.count("disass")) { - vm->setDisassEnabled(true); - LOGGER(disass)::reporting_level() = logging::INFO; - LOGGER(disass)::print_time() = false; - auto file_name = clim["disass"].as(); - if (file_name.length() > 0) { - LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); - LOGGER(disass)::print_severity() = false; - } - } - uint64_t start_address = 0; - if (clim.count("mem")) - vm->get_arch()->load_file(clim["mem"].as()); - if (clim.count("elf")) - for (std::string input : clim["elf"].as>()) { - auto start_addr = vm->get_arch()->load_file(input); - if (start_addr.second) start_address = start_addr.first; - } - for (std::string input : args) { - auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files - if (start_addr.second) start_address = start_addr.first; - } - if (clim.count("reset")) { - auto str = clim["reset"].as(); - start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10); - } - vm->reset(start_address); - auto cycles = clim["instructions"].as(); - res = vm->start(cycles, dump); - } catch (std::exception &e) { + return 127; + } + } + } + } + if (clim.count("disass")) { + vm->setDisassEnabled(true); + LOGGER(disass)::reporting_level() = logging::INFO; + LOGGER(disass)::print_time() = false; + auto file_name = clim["disass"].as(); + if (file_name.length() > 0) { + LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); + LOGGER(disass)::print_severity() = false; + } + } + uint64_t start_address = 0; + if (clim.count("mem")) + vm->get_arch()->load_file(clim["mem"].as()); + if (clim.count("elf")) + for (std::string input : clim["elf"].as>()) { + auto start_addr = vm->get_arch()->load_file(input); + if (start_addr.second) start_address = start_addr.first; + } + for (std::string input : args) { + auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files + if (start_addr.second) start_address = start_addr.first; + } + if (clim.count("reset")) { + auto str = clim["reset"].as(); + start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10); + } + vm->reset(start_address); + auto cycles = clim["instructions"].as(); + res = vm->start(cycles, dump); + } catch (std::exception &e) { LOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" - << std::endl; - res = 2; - } - // cleanup to let plugins report of needed - for (auto *p : plugin_list) { - delete p; - } - return res; -} + << std::endl; + res = 2; + } + // cleanup to let plugins report of needed + for (auto *p : plugin_list) { + delete p; + } + return res; +} diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index ffd4737..e3730f2 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -30,14 +30,16 @@ * *******************************************************************************/ -// clang-format off -#include -#include -#include -#include -#include +// clang-format off +#include +#include +#include +#include +#include #include -#include +#ifndef WIN32 +#include +#endif #include "core_complex.h" #include #include @@ -49,7 +51,7 @@ #include #include -// clang-format on +// clang-format on #define STR(X) #X #define CREATE_CORE(CN) \ @@ -68,12 +70,12 @@ using namespace scv_tr; #define GET_PROP_VALUE(P) P.getValue() #endif -#ifdef _MSC_VER -// not #if defined(_WIN32) || defined(_WIN64) because we have strncasecmp in mingw -#define strncasecmp _strnicmp -#define strcasecmp _stricmp -#endif - +#ifdef _MSC_VER +// not #if defined(_WIN32) || defined(_WIN64) because we have strncasecmp in mingw +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + namespace sysc { namespace tgfs { using namespace std; @@ -296,7 +298,7 @@ public: CREATE_CORE(tgc_d_xrb_nn) #endif { - LOG(ERR) << "Illegal argument value for core type: " << type << std::endl; + LOG(ERR) << "Illegal argument value for core type: " << type << std::endl; } auto *srv = debugger::server::get(); if (srv) tgt_adapter = srv->get_target(); @@ -409,6 +411,7 @@ void core_complex::before_end_of_elaboration() { cpu->vm->register_plugin(*plugin); plugin_list.push_back(plugin); } else { +#ifndef WIN32 std::array a{{filename.c_str()}}; iss::plugin::loader l(plugin_name, {{"initPlugin"}}); auto* plugin = l.call_function("initPlugin", a.size(), a.data()); @@ -416,6 +419,7 @@ void core_complex::before_end_of_elaboration() { cpu->vm->register_plugin(*plugin); plugin_list.push_back(plugin); } else +#endif SCCERR(SCMOD) << "Unknown plugin '" << plugin_name << "' or plugin not found"; } } diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 14ff892..c51b1b1 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -30,11 +30,10 @@ * *******************************************************************************/ -#include -#include -#include #include #include +#include +#include #include #include #include