From 5a31988a9d389db6e3862fc611125e11fe75362c Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 11 Feb 2018 21:17:23 +0000 Subject: [PATCH] Added 1st version of plugin interface --- incl/iss/arch_if.h | 6 +++++ incl/iss/vm_base.h | 32 ++++++++++++++++++++++++--- incl/iss/vm_if.h | 10 ++++++++- incl/iss/vm_plugin.h | 52 ++++++++++++++++++++++++++++++++++++++++++++ src/vm_base.cpp | 7 ++++++ 5 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 incl/iss/vm_plugin.h diff --git a/incl/iss/arch_if.h b/incl/iss/arch_if.h index 28c73d7..e07b337 100644 --- a/incl/iss/arch_if.h +++ b/incl/iss/arch_if.h @@ -85,6 +85,12 @@ class arch_if { * execution phases: instruction start and end */ enum exec_phase { ISTART, IEND, BSTART, BEND }; + /** + * get the name of this architecture + * + * @return the name of this architecture + */ + virtual const std::string core_type_name() const = 0; /** * reset the core * diff --git a/incl/iss/vm_base.h b/incl/iss/vm_base.h index 552d0f0..d03d5ed 100644 --- a/incl/iss/vm_base.h +++ b/incl/iss/vm_base.h @@ -43,6 +43,7 @@ #include "util/ities.h" #include "util/range_lut.h" #include "vm_if.h" +#include "vm_plugin.h" #include @@ -70,6 +71,11 @@ enum continuation_e { CONT, BRANCH, FLUSH, TRAP }; void add_functions_2_module(llvm::Module *mod); template class vm_base : public debugger_if, public vm_if { + struct plugin_entry { + sync_type sync; + vm_plugin& plugin; + llvm::Value* plugin_ptr; + }; public: using reg_e = typename arch::traits::reg_e; using sr_flag_e = typename arch::traits::sreg_flag_e; @@ -216,8 +222,7 @@ template class vm_base : public debugger_if, public vm_if { , core_id(core_id) , cluster_id(cluster_id) , regs_base_ptr(core.get_regs_base_ptr()) - , sync_exec(NO_SYNC) // TODO: should be NO_SYNC but this needs - // to changes code generation + , sync_exec(NO_SYNC) , jitHelper() , builder(jitHelper.builder()) , mod(nullptr) @@ -225,11 +230,19 @@ template class vm_base : public debugger_if, public vm_if { , leave_blk(nullptr) , trap_blk(nullptr) , tgt_adapter(nullptr) { - sync_exec = static_cast(sync_exec | core.needed_sync()); + sync_exec = static_cast(sync_exec | core.needed_sync()); } ~vm_base() override { delete tgt_adapter; } + void register_plugin(vm_plugin& plugin ){ + if(plugin.registration("1.0", *this)){ + llvm::Value* ptr = //this->builder.CreateIntToPtr(&plugin, get_type(8)->getPointerTo(0)); + llvm::ConstantInt::get(getContext(), llvm::APInt(64, (uint64_t)&plugin)); //TODO: this is definitely non-portable and wrong + plugins.push_back(plugin_entry{plugin.get_sync(), plugin, ptr}); + } + } + inline llvm::Type *get_type(unsigned width) const { assert(width > 0); if (width < 2) @@ -456,6 +469,18 @@ template class vm_base : public debugger_if, public vm_if { } if ((s & sync_exec)) builder.CreateCall(mod->getFunction("notify_phase"), std::vector{core_ptr, gen_const(32, notifier_mapping[s])}); + for(plugin_entry e: plugins){ + if(e.sync & s) + // callback(unsigned core_id = 0, unsigned cluster_id = 0, sync_type phase, uint64_t pc, unsigned instr_id) + builder.CreateCall(mod->getFunction("call_plugin"), + std::vector{ + e.plugin_ptr, + gen_const(32, core_id), + gen_const(32, cluster_id), + gen_const(32, s), + gen_const(32, inst_id) + }); + } } virtual llvm::Function *open_block_func() { @@ -507,6 +532,7 @@ template class vm_base : public debugger_if, public vm_if { std::stack> processing_pc; //std::vector loaded_regs{arch::traits::NUM_REGS, nullptr}; iss::debugger::target_adapter_base *tgt_adapter; + std::vector plugins; }; } } diff --git a/incl/iss/vm_if.h b/incl/iss/vm_if.h index e92b362..1159745 100644 --- a/incl/iss/vm_if.h +++ b/incl/iss/vm_if.h @@ -37,13 +37,21 @@ #include "vm_types.h" #include +#include namespace iss { // forward declaration class arch_if; +class vm_plugin; -class vm_if { +class vm_if { // @suppress("Class has a virtual method and non-virtual destructor") public: + /** + * register a plugin to the virtual machine + * + * @param plugin reference to the plugin to be registered + */ + virtual void register_plugin(vm_plugin& plugin) = 0; /** * get the underlying class of the core to be simulated * diff --git a/incl/iss/vm_plugin.h b/incl/iss/vm_plugin.h new file mode 100644 index 0000000..8bb0b04 --- /dev/null +++ b/incl/iss/vm_plugin.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 _ISS_VM_PLUGIN_H_ +#define _ISS_VM_PLUGIN_H_ + +#include "vm_if.h" +#include + +namespace iss { +class vm_plugin { // @suppress("Class has a virtual method and non-virtual destructor") +public: + virtual bool registration(const char* const version, vm_if& arch) = 0; + + virtual sync_type get_sync() = 0; + + virtual void callback(unsigned core_id, unsigned cluster_id, sync_type phase, unsigned instr_id) = 0; +}; +} + +#endif /* DBT_CORE_INCL_ISS_VM_PLUGIN_H_ */ diff --git a/src/vm_base.cpp b/src/vm_base.cpp index 7cc3057..093438a 100644 --- a/src/vm_base.cpp +++ b/src/vm_base.cpp @@ -34,6 +34,7 @@ #include #include +#include #include @@ -92,6 +93,7 @@ void add_functions_2_module(Module *mod) { FDECL(print_disass, VOID_TYPE, THIS_PTR_TYPE, INT_TYPE(64), INT_TYPE(8)->getPointerTo()); FDECL(pre_instr_sync, VOID_TYPE, THIS_PTR_TYPE); FDECL(notify_phase, VOID_TYPE, THIS_PTR_TYPE, INT_TYPE(32)); + FDECL(call_plugin, VOID_TYPE, THIS_PTR_TYPE, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32)); } } @@ -198,5 +200,10 @@ void pre_instr_sync(this_t iface) { void notify_phase(this_t iface, uint32_t phase) { ((iss::arch_if *)iface)->notify_phase((iss::arch_if::exec_phase)phase); } + +void call_plugin(this_t iface, uint32_t core_id, uint32_t cluster_id, uint32_t phase, uint32_t instr_id) { + ((iss::vm_plugin*)iface)->callback((unsigned)core_id, (unsigned)cluster_id, (iss::sync_type)phase, (unsigned)instr_id); +} + }