From ae4322c1b967e7d9e98ff30a3cb7bd94476e9ada Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 15 Oct 2023 09:03:31 +0200 Subject: [PATCH] =?UTF-8?q?=E2=80=9Esrc/main.cpp=E2=80=9C=20=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.cpp | 444 +++++++++++++++++++++++++-------------------------- 1 file changed, 222 insertions(+), 222 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bd9638c..03a68d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,222 +1,222 @@ -/******************************************************************************* - * 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 -#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" -#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()->default_value(4), "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 ISS backend to use, options are: interp, tcc") - ("isa", po::value()->default_value("tgc5c"), "core or isa name to use for simulation, use '?' to get list"); - // 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; - 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"); - auto & f = iss::core_factory::instance(); - // instantiate the simulator - iss::vm_ptr vm{nullptr}; - iss::cpu_ptr cpu{nullptr}; - std::string isa_opt(clim["isa"].as()); - if(isa_opt.size()==0 || isa_opt == "?") { - auto list = f.get_names(); - std::sort(std::begin(list), std::end(list)); - std::cout<<"Available implementations (core|platform|backend):\n - "<(), clim["gdb-port"].as()); - } else { - auto base_isa = isa_opt.substr(0, 5); - if(base_isa=="tgc5d" || base_isa=="tgc5e") { - isa_opt += "|mu_p_clic_pmp|"+clim["backend"].as(); - } else { - isa_opt += "|m_p|"+clim["backend"].as(); - } - std::tie(cpu, vm) = f.create(isa_opt, clim["gdb-port"].as()); - } - if(!cpu ){ - LOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " <()<< std::endl; - return 127; - } - if(!vm ){ - LOG(ERR) << "Could not create vm for isa " << isa_opt << " and backend " <()<< 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 arg{""}; - std::size_t found = opt_val.find('='); - if (found != std::string::npos) { - plugin_name = opt_val.substr(0, found); - arg = opt_val.substr(found + 1, opt_val.size()); - } -#if defined(WITH_PLUGINS) - if (plugin_name == "ic") { - auto *ic_plugin = new iss::plugin::instruction_count(arg); - vm->register_plugin(*ic_plugin); - plugin_list.push_back(ic_plugin); - } else if (plugin_name == "ce") { - auto *ce_plugin = new iss::plugin::cycle_estimate(arg); - vm->register_plugin(*ce_plugin); - plugin_list.push_back(ce_plugin); - } else -#endif - { -#if !defined(WIN32) - std::vector a{}; - if(arg.length()) - a.push_back({arg.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) { - 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; -} +/******************************************************************************* + * 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 +#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" +#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()->default_value(4), "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 ISS backend to use, options are: interp, tcc") + ("isa", po::value()->default_value("tgc5c"), "core or isa name to use for simulation, use '?' to get list"); + // 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-TGC simulator for TGC RISC-V cores" << 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; + 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"); + auto & f = iss::core_factory::instance(); + // instantiate the simulator + iss::vm_ptr vm{nullptr}; + iss::cpu_ptr cpu{nullptr}; + std::string isa_opt(clim["isa"].as()); + if(isa_opt.size()==0 || isa_opt == "?") { + auto list = f.get_names(); + std::sort(std::begin(list), std::end(list)); + std::cout<<"Available implementations (core|platform|backend):\n - "<(), clim["gdb-port"].as()); + } else { + auto base_isa = isa_opt.substr(0, 5); + if(base_isa=="tgc5d" || base_isa=="tgc5e") { + isa_opt += "|mu_p_clic_pmp|"+clim["backend"].as(); + } else { + isa_opt += "|m_p|"+clim["backend"].as(); + } + std::tie(cpu, vm) = f.create(isa_opt, clim["gdb-port"].as()); + } + if(!cpu ){ + LOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " <()<< std::endl; + return 127; + } + if(!vm ){ + LOG(ERR) << "Could not create vm for isa " << isa_opt << " and backend " <()<< 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 arg{""}; + std::size_t found = opt_val.find('='); + if (found != std::string::npos) { + plugin_name = opt_val.substr(0, found); + arg = opt_val.substr(found + 1, opt_val.size()); + } +#if defined(WITH_PLUGINS) + if (plugin_name == "ic") { + auto *ic_plugin = new iss::plugin::instruction_count(arg); + vm->register_plugin(*ic_plugin); + plugin_list.push_back(ic_plugin); + } else if (plugin_name == "ce") { + auto *ce_plugin = new iss::plugin::cycle_estimate(arg); + vm->register_plugin(*ce_plugin); + plugin_list.push_back(ce_plugin); + } else +#endif + { +#if !defined(WIN32) + std::vector a{}; + if(arg.length()) + a.push_back({arg.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) { + 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; +}