50 : start(start), end(end), execBlock(execBlock), jitlib(lib)
66 template <
unsigned len,
unsigned pos>
71 template <
unsigned len,
unsigned pos>
75 call_initCodeBlock<len, pos + 1>(ca, cb);
78 template <
unsigned len,
unsigned pos>
84 template <
unsigned len,
unsigned pos>
89 call_finalizeCodeBlock<len, pos + 1>(ca, cb);
95 while (ca[pos] !=
nullptr)
103 while (ca[pos] !=
nullptr)
111 static std::mutex mu;
113 std::lock_guard<std::mutex> lock(mu);
121 , arch_(archptr_.get())
122 , jit_(jitptr_.get())
127 , plugins_handle_array_(0)
129 #
if ETISS_TRANSLATOR_STAT
156 if (
arch_ ==
nullptr)
165 std::vector<etiss::TranslationPlugin *> tmpl;
167 tmpl.push_back(
arch_);
189 for (
size_t i = 0; i < tmpl.size(); i++)
203 for (
size_t i = 0; i < tmpl.size(); i++)
208 for (
int i = (
int)tmpl.size() - 1; i >= 0; i--)
268 if (prev != 0 && !prev->
valid)
274 std::list<BlockLink *> &list =
blockmap_[instructionindex >> 9];
275 for (std::list<BlockLink *>::iterator iter = list.begin(); iter != list.end();)
282 if (iterbl->
start <= instructionindex && iterbl->
end > instructionindex)
313 std::string blockfunctionname;
315 std::stringstream ss;
316 ss <<
"_t" <<
id <<
"c" <<
tblockcount++ <<
"_block_" << instructionindex;
317 blockfunctionname = ss.str();
322 "#include \"etiss/jit/System.h\"\n"
323 "#include \"etiss/jit/libresources.h\"\n"
324 "#include \"etiss/jit/libsemihost.h\"\n"
325 "#include \"etiss/jit/ReturnCode.h\"\n"
326 "#include \"etiss/jit/libCSRCounters.h\"\n");
329 if(it !=
"") block.
fileglobalCode().insert(
"#include \"" + it +
"\"\n");
333 ") return ETISS_RETURNCODE_RELOADCURRENTBLOCK;");
339 if (transerror != ETISS_RETURNCODE_NOERROR)
349 std::stringstream ss;
350 block.
toCode(ss, blockfunctionname,
nullptr);
355 std::set<std::string> headers;
359 if(it !=
"") headers.insert(it);
362 std::set<std::string> libloc;
364 libloc.insert(
etiss::cfg().get<std::string>(
"etiss_path",
"./"));
371 std::set<std::string> libs;
373 libs.insert(
"resources");
374 libs.insert(
"semihost");
375 libs.insert(
"CSRCounters");
377 if(it !=
"") libs.insert(it);
391 #define ETISS_DEBUG 1
404 auto local_jit =
jit_;
405 std::shared_ptr<void> lib(funcs, [local_jit](
void *p) { local_jit->free(p); });
415 uint64 ii9 = instructionindex >> 9;
438 etiss::log(
etiss::ERROR, std::string(
"Failed to acquire function pointer from compiled library:") + error);
457 const unsigned maxcount =
etiss::cfg().
get<
unsigned>(
"etiss.max_block_size", 100);
464 return etiss::RETURNCODE::GENERALERROR;
486 if (ret == etiss::RETURNCODE::IBUS_READ_ERROR || ret == etiss::RETURNCODE::DBUS_READ_ERROR)
488 std::cout <<
"Instruction bus read error while translating!" << std::endl;
489 errba.
set_value(etiss::RETURNCODE::IBUS_READ_ERROR);
493 bool ok = instr->translate(errba, line.
getCodeSet(), context);
495 return etiss::RETURNCODE::GENERALERROR;
549 errba.
set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
554 instr = instrSet->
resolve(*secba);
557 errba.
set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
566 return etiss::RETURNCODE::GENERALERROR;
577 errba.
set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
584 return etiss::RETURNCODE::GENERALERROR;
599 entry.second.erase(std::remove_if(entry.second.begin(), entry.second.end(),
603 BlockLink::updateRef(bl->next, 0);
604 BlockLink::updateRef(bl->branch, 0);
605 BlockLink::decrRef(bl);
623 const etiss::uint64 endindexblock = (endindex >> 9) + ((((endindex >> 9) << 9) == endindex) ? 0 : 1);
624 for (
etiss::uint64 block = startindexblock; block < endindexblock; block++)
631 for (std::list<BlockLink *>::iterator iter = entry->second.begin(); iter != entry->second.end();)
634 if (bl->
start < endindex || bl->
end > startindex)
639 entry->second.erase(iter++);
647 if (entry->second.empty())
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
static __inline__ uint64_t
static __inline__ uint8_t
structure to store additional information with a function pointer to the translated code
static void updateRef(BlockLink *&link, BlockLink *newValue)
change the value of a BlockLink pointer.
const etiss::uint64 end
end instruction index (excluded)
BlockLink * next
next block; ONLY MODIFY WITH updateRef
unsigned refcount
number of references to this instance; DO NOT MODIFY
const etiss::uint64 start
start instruction index
BlockLink(etiss::uint64 start, etiss::uint64 end, ExecBlockCall execBlock, std::shared_ptr< void > lib)
static void decrRef(BlockLink *&link)
decrease reference count to a BlockLink and delete the instance if no other references exist
BlockLink * branch
last branch block; ONLY MODIFY WITH updateRef
bool valid
true if the associated function implements current code
static void incrRef(BlockLink *link)
increase reference count to a BlockLink
virtual std::string getIncludePath()
returns a path that will be used to look up header files
virtual void compensateEndianess(ETISS_CPU *cpu, etiss::instr::BitArray &ba) const
this function should compensate for any endianess on a BitArray so that bit 0 is always the LSB.
std::string getName() const
returns the name of this architecture.
equivalent of a translated instruction
void toCode(std::stringstream &out, const std::string &funcname, std::set< std::string > *fileglobalcode)
std::set< std::string > & functionglobalCode()
std::set< std::string > & fileglobalCode()
Line & append(etiss::uint64 addr)
etiss::uint64 endaddress_
etiss::uint64 startindex_
T get(const std::string &key, T default_, bool *default_used=0)
template function to read the value of a configuration key.
virtual void * translate(std::string code, std::set< std::string > headerpaths, std::set< std::string > librarypaths, std::set< std::string > libraries, std::string &error, bool debug=true)=0
translate C code to executable code and return a handle/pointer that identifies the compilation resul...
virtual void * getFunction(void *handle, std::string name, std::string &error)=0
returns a function pointer to a compiled function from the handle returned by etiss::JIT::translate
base plugin class that provides access to different plugin functions if present
TranslationPlugin * getTranslationPlugin()
allows to add code to the translation of instructions
virtual void initCodeBlock(etiss::CodeBlock &) const
called before instructions are translated for the code block
virtual void finalizeInstrSet(etiss::instr::ModedInstructionSet &) const
called after all instructions have been added to allow last changes
virtual void finalizeCodeBlock(etiss::CodeBlock &) const
called after all instructions have been translated for the code block
virtual void initInstrSet(etiss::instr::ModedInstructionSet &) const
called to add instructions to the instruction set
virtual void * getPluginHandle()
called to get the handle that is available in translated code via getPoinerCode()....
Translation(std::shared_ptr< etiss::CPUArch > &arch, std::shared_ptr< etiss::JIT > &jit, std::list< std::shared_ptr< etiss::Plugin >> &plugins, ETISS_System &system, ETISS_CPU &cpu)
std::string disasm(uint8_t *buf, unsigned len, int &append)
etiss::instr::ModedInstructionSet * mis_
uint64_t tblockcount
countes translated blocks. needed to guarantee unique block function names
std::list< std::shared_ptr< etiss::Plugin > > & plugins_
size_t plugins_array_size_
etiss::TranslationPlugin ** plugins_array_
void unloadBlocks(etiss::uint64 startindex=0, etiss::uint64 endindex=((etiss::uint64)((etiss::int64) -1)))
etiss::CPUArch *const arch_
void ** plugins_handle_array_
std::unordered_map< etiss::uint64, std::list< BlockLink * > > blockmap_
etiss::int32 translateBlock(CodeBlock &cb)
void(* plugins_finalizeCodeBlock_)(etiss::TranslationPlugin **, CodeBlock &)
Function pointer, the function is getting defined in Translation::init via template function etiss::c...
BlockLink * getBlock(BlockLink *prev, const etiss::uint64 &instructionindex)
void(* plugins_initCodeBlock_)(etiss::TranslationPlugin **, CodeBlock &)
Function pointer, the function is getting defined in Translation::init via template function etiss::c...
void set_value(size_type width, unsigned long value)
change the value the object is holding
unsigned byteCount() const
unsigned intCount() const
Buffer for reading data from memory while instructions are being fetched.
char * internalBuffer()
get the internal buffer
this class contains parameters that persist in between instruction lookpus/translation within a trans...
uint64_t current_local_address_
address within the current block
bool is_not_default_width_
if true the this instruction is not as long as the width of the variable instruction set
bool force_block_end_
if true then the block ends after the current instruction.
bool instr_width_fully_evaluated_
if true the length_updater_ function will be called again after instr_width_ bits are available
uint64_t current_address_
start address of current instruction
bool force_append_next_instr_
if true then the block will continue with the next instruction and cannot be terminated
holds etiss::instr::Instruction instances and handles automatic instruction tree creation.
Instruction & getInvalid()
Instruction * resolve(BitArray &instr)
holds information and translation callbacks for an instruction.
bool translate(BitArray &, CodeSet &cs, InstructionContext &context)
std::string printASM(BitArray &)
holds etiss::instr::VariableInstructionSet instances for different modes.
VariableInstructionSet * get(uint32_t mode)
holds etiss::instr::InstructionSet instances with different bit widths.
InstructionSet * get(unsigned width)
std::function< void(VariableInstructionSet &, InstructionContext &, BitArray &)> length_updater_
InstructionSet * getMain()
MM_EXPORT const int32_t NOERROR
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
std::string jitFiles()
Get ETISS JIT files path.
std::vector< std::string > jitExtLibPaths()
Get ETISS JIT external path.
std::string toString(const T &val)
conversion of type T to std::string.
static uint64_t genTranslationId()
static std::enable_if< len==pos, void >::type call_initCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
etiss::int32(* ExecBlockCall)(ETISS_CPU *cpu, ETISS_System *system, void **plugin_pointers)
std::vector< std::string > jitExtLibraries()
Get ETISS JIT external libraries.
std::vector< std::string > jitExtHeaders()
Get ETISS JIT external headers.
std::vector< std::string > jitExtHeaderPaths()
Get ETISS JIT external path.
Configuration & cfg(const std::string &cfgName)
Get reference of the global ETISS configuration object.
static void call_initCodeBlock_ul(etiss::TranslationPlugin **ca, CodeBlock &cb)
static std::enable_if< len==pos, void >::type call_finalizeCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
static void call_finalizeCodeBlock_ul(etiss::TranslationPlugin **ca, CodeBlock &cb)
void log(Verbosity level, std::string msg)
write log message at the given level.
basic cpu state structure needed for execution of any cpu architecture.
etiss_uint32 mode
instruction set mode of the processor
memory access and time synchronization functions.
void * handle
custom handle that will be passed to the functions of this structure
etiss_int32(* dbg_read)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug read