ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
Translation.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2//
3// This file is part of ETISS. It is licensed under the BSD 3-Clause License; you may not use this file except in
4// compliance with the License. You should have received a copy of the license along with this project. If not, see the
5// LICENSE file.
6
7#include "etiss/Translation.h"
8#include "etiss/CPUArch.h"
9#include "etiss/Instruction.h"
10#include "etiss/JIT.h"
11#include "etiss/jit/ReturnCode.h"
12#include <mutex>
13
14namespace etiss
15{
16
17BlockLink::BlockLink(etiss::uint64 start, etiss::uint64 end, ExecBlockCall execBlock, std::shared_ptr<void> lib)
18 : start(start), end(end), execBlock(execBlock), jitlib(lib)
19{
20 refcount = 0;
21 next = 0;
22 branch = 0;
23 valid = true;
24}
25
33
34template <unsigned len, unsigned pos>
35static typename std::enable_if<len == pos, void>::type call_initCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
36{
37 return;
38}
39template <unsigned len, unsigned pos>
40static typename std::enable_if<len != pos, void>::type call_initCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
41{
42 ca[pos]->initCodeBlock(cb);
43 call_initCodeBlock<len, pos + 1>(ca, cb);
44}
45
46template <unsigned len, unsigned pos>
47static typename std::enable_if<len == pos, void>::type call_finalizeCodeBlock(etiss::TranslationPlugin **ca,
48 CodeBlock &cb)
49{
50 return;
51}
52template <unsigned len, unsigned pos>
53static typename std::enable_if<len != pos, void>::type call_finalizeCodeBlock(etiss::TranslationPlugin **ca,
54 CodeBlock &cb)
55{
56 ca[pos]->finalizeCodeBlock(cb);
57 call_finalizeCodeBlock<len, pos + 1>(ca, cb);
58}
59
61{
62 size_t pos = 0;
63 while (ca[pos] != nullptr)
64 {
65 ca[pos++]->initCodeBlock(cb);
66 }
67}
69{
70 size_t pos = 0;
71 while (ca[pos] != nullptr)
72 {
73 ca[pos++]->finalizeCodeBlock(cb);
74 }
75}
76
78{
79 static std::mutex mu;
80 static uint64_t id = 0;
81 std::lock_guard<std::mutex> lock(mu);
82 return id++;
83}
84
85Translation::Translation(std::shared_ptr<etiss::CPUArch> &arch, std::shared_ptr<etiss::JIT> &jit,
86 std::list<std::shared_ptr<etiss::Plugin>> &plugins, ETISS_System &system, ETISS_CPU &cpu)
87 : archptr_(arch)
88 , jitptr_(jit)
89 , arch_(archptr_.get())
90 , jit_(jitptr_.get())
91 , plugins_(plugins)
92 , system_(system)
93 , cpu_(cpu)
94 , plugins_array_(0)
95 , plugins_handle_array_(0)
96 , mis_(0)
97#if ETISS_TRANSLATOR_STAT
98 , next_count_(0)
99 , branch_count_(0)
100 , miss_count_(0)
101#endif
102 , id(genTranslationId())
103{
104 tblockcount = 0;
105}
106
108{
109 unloadBlocks(0, (uint64_t)((int64_t)-1));
110 delete[] plugins_array_;
111 delete[] plugins_handle_array_;
112 delete mis_;
113}
114
116{
117 delete[] plugins_array_;
118 plugins_array_ = 0;
119 delete[] plugins_handle_array_;
121 delete mis_;
122 mis_ = 0;
123
124 if (arch_ == nullptr)
125 return nullptr;
126
127 if (jit_ == nullptr)
128 return nullptr;
129
130 // First plugin to more to tmpl list is the architecture plugin
132
133 std::vector<etiss::TranslationPlugin *> tmpl;
134
135 tmpl.push_back(arch_);
136
137 // Followed by all plugins, which are of type translation plugin
138 for (auto iter = plugins_.begin(); iter != plugins_.end(); iter++)
139 {
140 etiss::Plugin *p = iter->get();
141 if (p != nullptr)
142 {
144 if (tp != nullptr)
145 {
146 tmpl.push_back(tp);
147 }
148 }
149 }
150
151 // Build up the plugin lists
152 plugins_array_ = new etiss::TranslationPlugin *[tmpl.size() + 1];
153 plugins_array_[tmpl.size()] = nullptr;
154 plugins_handle_array_ = new void *[tmpl.size()];
155 plugins_array_size_ = tmpl.size();
156
157 for (size_t i = 0; i < tmpl.size(); i++)
158 {
159 plugins_array_[i] = tmpl[i];
161 /* During execution of each code block, the list plugin_handle_, which
162 returned by the function init, is passed again as parameter with name
163 plugin_pointers
164 -> plugin_pointers is the name of the list of translation plugin in the
165 generated c-code of all code blocks
166 */
167 plugins_array_[i]->pointerCode = std::string("(plugin_pointers[") + toString(i) + "])";
168 }
169
170 // Call the function initInstrSet for all translation plugins
171 for (size_t i = 0; i < tmpl.size(); i++)
172 {
174 }
175 // Call the function finalizeInstrSet( for all translation plugins
176 for (int i = (int)tmpl.size() - 1; i >= 0; i--)
177 {
179 }
180
182
183 if (!mis_->compile())
184 {
185 etiss::log(etiss::ERROR, "Failed to compile instruction set");
186 delete[] plugins_array_;
187 plugins_array_ = 0;
188 delete[] plugins_handle_array_;
190 delete mis_;
191 mis_ = 0;
192 }
193
194 // Builds the function for function pointer plugins_initCodeBlock_ It calls_initCodeBlock functions of all
195 // translation plugins Builds the functions plugins_finalizeCodeBlock_ It calls_finalizeCodeBlock functions of all
196 // translation plugins
197 switch (plugins_array_size_)
198 {
199 case 1:
200 plugins_initCodeBlock_ = &(call_initCodeBlock<1, 0>);
201 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<1, 0>);
202 break;
203 case 2:
204 plugins_initCodeBlock_ = &(call_initCodeBlock<2, 0>);
205 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<2, 0>);
206 break;
207 case 3:
208 plugins_initCodeBlock_ = &(call_initCodeBlock<3, 0>);
209 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<3, 0>);
210 break;
211 case 4:
212 plugins_initCodeBlock_ = &(call_initCodeBlock<4, 0>);
213 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<4, 0>);
214 break;
215 case 5:
216 plugins_initCodeBlock_ = &(call_initCodeBlock<5, 0>);
217 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<5, 0>);
218 break;
219 case 6:
220 plugins_initCodeBlock_ = &(call_initCodeBlock<6, 0>);
221 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<6, 0>);
222 break;
223 default:
226 }
227
229}
230
231BlockLink *Translation::getBlock(BlockLink *prev, const etiss::uint64 &instructionindex)
232{
233
234 std::string error;
235
236 if (prev != 0 && !prev->valid)
237 {
238 prev = 0;
239 }
240
241 // search block in cache
242 std::list<BlockLink *> &list = blockmap_[instructionindex >> 9];
243 for (std::list<BlockLink *>::iterator iter = list.begin(); iter != list.end();) // iter++ moved into block
244 {
245 BlockLink *iterbl = (*iter);
246 if (iterbl != 0)
247 {
248 if (iterbl->valid) // check for valid block
249 {
250 if (iterbl->start <= instructionindex && iterbl->end > instructionindex)
251 {
252 if (prev != 0)
253 {
254 if (prev->end == iterbl->start)
255 {
256 BlockLink::updateRef(prev->next, iterbl);
257 }
258 else
259 {
260 BlockLink::updateRef(prev->branch, iterbl);
261 }
262 }
263 return *iter;
264 }
265 iter++;
266 }
267 else // cleanup
268 {
269 BlockLink::updateRef(iterbl->next, 0);
270 BlockLink::updateRef(iterbl->branch, 0);
271 list.erase(iter++);
273 iterbl); // remove reference of map // prev remains valid because this blocklink needs to be invalid
274 continue;
275 }
276 }
277 }
278
279 // generate block
280
281 std::string blockfunctionname;
282 {
283 std::stringstream ss;
284 ss << "_t" << id << "c" << tblockcount++ << "_block_" << instructionindex;
285 blockfunctionname = ss.str();
286 }
287
288 CodeBlock block(instructionindex);
289
290#ifdef ETISS_USE_COREDSL_COVERAGE
291 block.fileglobalCode().insert("#define ETISS_USE_COREDSL_COVERAGE");
292#endif
293
294 block.fileglobalCode().insert("#include \"etiss/jit/CPU.h\"\n"
295 "#include \"etiss/jit/System.h\"\n"
296 "#include \"etiss/jit/libresources.h\"\n"
297 "#include \"etiss/jit/libsemihost.h\"\n"
298 "#include \"etiss/jit/ReturnCode.h\"\n"
299 "#include \"etiss/jit/libCSRCounters.h\"\n");
300
301 for (auto &it : jitExtHeaders())
302 {
303 if (it != "")
304 block.fileglobalCode().insert("#include \"" + it + "\"\n");
305 }
306
307 block.functionglobalCode().insert("if (cpu->mode != " + toString(cpu_.mode) +
308 ") return ETISS_RETURNCODE_RELOADCURRENTBLOCK;");
309
311
312 etiss::int32 transerror = translateBlock(block);
313
314 if (transerror != ETISS_RETURNCODE_NOERROR)
315 {
316 etiss::log(etiss::ERROR, "Failed to translate block");
317 return nullptr;
318 }
319
321
322 std::string code;
323 {
324 std::stringstream ss;
325 block.toCode(ss, blockfunctionname, nullptr);
326 code = ss.str();
327 }
328
329 // various includes
330 std::set<std::string> headers;
331 headers.insert(etiss::jitFiles());
332 headers.insert(arch_->getIncludePath());
333 for (auto &it : jitExtHeaderPaths())
334 {
335 if (it != "")
336 headers.insert(it);
337 }
338
339 std::set<std::string> libloc;
340 libloc.insert(arch_->getIncludePath());
341 libloc.insert(etiss::cfg().get<std::string>("etiss_path", "./"));
342 libloc.insert(etiss::jitFiles());
343 libloc.insert(etiss::jitFiles() + "/etiss/jit");
344 for (auto &it : jitExtLibPaths())
345 {
346 if (it != "")
347 libloc.insert(etiss::jitFiles() + it);
348 }
349
350 std::set<std::string> libs;
351 // libs.insert("ETISS");
352 libs.insert("resources");
353 libs.insert("semihost");
354 libs.insert("CSRCounters");
355 for (auto &it : jitExtLibraries())
356 {
357 if (it != "")
358 libs.insert(it);
359 }
360 /* DEBUG HELPER: write code files to work directory
361 {
362 static unsigned count = 0;
363 std::stringstream ss;
364 ss << "code" << ++count;
365 std::ofstream out;
366 out.open(ss.str().c_str());
367 out << code;
368 std::cout << "Code file " << count << std::endl;
369 }
370 */
371#ifndef ETISS_DEBUG
372#define ETISS_DEBUG 0
373#endif
374 // compile library
375 void *funcs =
376 jit_->translate(code, headers, libloc, libs, error, etiss::cfg().get<bool>("jit.debug", ETISS_DEBUG) != 0);
377
378 if (funcs == 0)
379 {
380 etiss::log(etiss::ERROR, error);
381 return 0;
382 }
383
384 // wrap library handle for cleanup
385 auto local_jit = jit_;
386 std::shared_ptr<void> lib(funcs, [local_jit](void *p) { local_jit->free(p); });
387
388 // check function/library handle
389 if (lib.get() != 0)
390 {
391 // std::cout<<"blockfunctionname:"<<blockfunctionname<<std::endl;
392 ExecBlockCall execBlock = (ExecBlockCall)jit_->getFunction(lib.get(), blockfunctionname.c_str(), error);
393 if (execBlock != 0)
394 {
395 BlockLink *nbl = new BlockLink(block.startindex_, block.endaddress_, execBlock, lib);
396 uint64 ii9 = instructionindex >> 9;
397 do
398 {
399 blockmap_[ii9].push_back(nbl);
400 BlockLink::incrRef(nbl); // map holds a reference
401 ii9++;
402 } while ((ii9 << 9) < block.endaddress_);
403
404 if (prev != 0)
405 {
406 if (nbl->start == prev->end)
407 {
408 BlockLink::updateRef(prev->next, nbl);
409 }
410 else
411 {
412 BlockLink::updateRef(prev->branch, nbl);
413 }
414 }
415 return nbl;
416 }
417 else
418 {
419 etiss::log(etiss::ERROR, std::string("Failed to acquire function pointer from compiled library:") + error);
420 return 0;
421 }
422 }
423
424 return 0;
425}
429{
430 cb.endaddress_ = cb.startindex_;
431
433
434 context.cf_delay_slot_ = 0;
435 context.force_block_end_ = false;
436
437 unsigned count = 0;
438 const unsigned maxcount = etiss::cfg().get<unsigned>("etiss.max_block_size", 100);
439 cb.reserve(maxcount);
440
442
443 if (vis_ == nullptr)
444 {
445 return etiss::RETURNCODE::GENERALERROR;
446 }
447
448 etiss::instr::BitArray mainba(vis_->width_);
450
451 do
452 {
453 context.force_append_next_instr_ = false;
454 context.force_block_end_ = false;
455 context.current_address_ = cb.endaddress_;
457 context.instr_width_fully_evaluated_ = true;
458 context.is_not_default_width_ = false;
459 context.instr_width_ = vis_->width_;
460
461 etiss::instr::BitArray errba(32, 0);
462
463 buffer = etiss::instr::Buffer(mainba.intCount());
464 // read instruction
465 etiss::int32 ret = (*system_.dbg_read)(system_.handle, cb.endaddress_, (etiss_uint8 *)buffer.internalBuffer(),
466 mainba.byteCount()); // read instruction
467 mainba.set_value(buffer.data());
468 if (ret == etiss::RETURNCODE::IBUS_READ_ERROR || ret == etiss::RETURNCODE::DBUS_READ_ERROR)
469 {
470 std::cout << "Instruction bus read error while translating!" << std::endl;
471 errba.set_value(etiss::RETURNCODE::IBUS_READ_ERROR);
472 // std::cout << "mainba.byteCount = " << mainba.byteCount() << std::endl;
473 auto instr = &vis_->getMain()->getInvalid();
474 CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
475 bool ok = instr->translate(errba, line.getCodeSet(), context);
476 if (unlikely(!ok))
477 {
478 return etiss::RETURNCODE::GENERALERROR;
479 }
480 cb.endaddress_ += mainba.byteCount(); // update end address
481 return etiss::RETURNCODE::NOERROR;
482 }
483 if (ret != etiss::RETURNCODE::NOERROR)
484 {
485 if (count == 0)
486 {
487 return ret; // empty block -> return error
488 }
489 else
490 {
491 break; // non empty block -> compile pending
492 }
493 }
494
495 arch_->compensateEndianess(&cpu_, mainba);
496 vis_->length_updater_(*vis_, context, mainba);
497
498 // continue reading instruction data if neccessary
499 if (unlikely(context.is_not_default_width_))
500 {
501 etiss::instr::BitArray *secba = nullptr;
502 do
503 {
504 if (secba)
505 delete secba;
506 secba = new etiss::instr::BitArray(context.instr_width_);
507
508 buffer = etiss::instr::Buffer(secba->intCount());
510 secba->byteCount()); // read instruction
511 secba->set_value(buffer.data());
512
513 if (ret != etiss::RETURNCODE::NOERROR)
514 {
515 if (count == 0)
516 {
517 delete secba;
518 return ret; // empty block -> return error
519 }
520 else
521 {
522 break; // non empty block -> compile pending
523 }
524 }
525 arch_->compensateEndianess(&cpu_, *secba);
526 vis_->length_updater_(*vis_, context, *secba);
527 } while (!context.instr_width_fully_evaluated_);
528
530 etiss::instr::InstructionSet *instrSet = vis_->get(secba->size());
531 if (unlikely(!instrSet))
532 {
533 errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
534 instr = &vis_->getMain()->getInvalid();
535 }
536 else
537 {
538 instr = instrSet->resolve(*secba);
539 if (unlikely(!instr))
540 {
541 errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
542 instr = &instrSet->getInvalid();
543 }
544 }
545 CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
546 bool ok =
547 instr->translate(errba != etiss::instr::BitArray(32, 0) ? errba : *secba, line.getCodeSet(), context);
548 if (unlikely(!ok))
549 {
550 delete secba;
551 return etiss::RETURNCODE::GENERALERROR;
552 }
553 cb.endaddress_ += secba->byteCount(); // update end address
554 delete secba;
555 }
556 else
557 {
558 etiss::instr::InstructionSet *instrSet = vis_->getMain();
559 etiss::instr::Instruction *instr = instrSet->resolve(mainba);
560 if (unlikely(instr == 0))
561 {
562 errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
563 instr = &instrSet->getInvalid();
564 }
565 CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
566 bool ok =
567 instr->translate(errba != etiss::instr::BitArray(32, 0) ? errba : mainba, line.getCodeSet(), context);
568 if (unlikely(!ok))
569 {
570 return etiss::RETURNCODE::GENERALERROR;
571 }
572 cb.endaddress_ += mainba.byteCount(); // update end address
573 }
574
575 count++;
576 } while ((count < maxcount && !context.force_block_end_) || context.force_append_next_instr_);
577
578 return etiss::RETURNCODE::NOERROR;
579}
580
582{
583 for (auto &entry : blockmap_)
584 {
585 entry.second.erase(std::remove_if(entry.second.begin(), entry.second.end(),
586 [](auto &bl)
587 {
588 bl->valid = false;
589 BlockLink::updateRef(bl->next, 0);
590 BlockLink::updateRef(bl->branch, 0);
591 BlockLink::decrRef(bl); // remove reference of map
592 return true;
593 }),
594 entry.second.end());
595 }
596 blockmap_.clear();
597}
598
599void Translation::unloadBlocks(etiss::uint64 startindex, etiss::uint64 endindex)
600{
601 // Hotfix: if everything needs to be deleted, new function unloadBlocksAll()
602 if (startindex == 0 && endindex == ((etiss::uint64)((etiss::int64)-1)))
603 {
605 return;
606 }
607
608 const etiss::uint64 startindexblock = startindex >> 9;
609 const etiss::uint64 endindexblock = (endindex >> 9) + ((((endindex >> 9) << 9) == endindex) ? 0 : 1);
610 for (etiss::uint64 block = startindexblock; block < endindexblock; block++)
611 {
612 if (blockmap_.empty())
613 break;
614 auto entry = blockmap_.find(block);
615 if (entry != blockmap_.end())
616 {
617 for (std::list<BlockLink *>::iterator iter = entry->second.begin(); iter != entry->second.end();)
618 {
619 BlockLink *bl = *iter;
620 if (bl->start < endindex || bl->end > startindex)
621 {
622 bl->valid = false;
625 entry->second.erase(iter++);
626 BlockLink::decrRef(bl); // remove reference of map
627 }
628 else
629 {
630 iter++;
631 }
632 }
633 if (entry->second.empty())
634 blockmap_.erase(entry);
635 }
636 }
637}
638
639std::string Translation::disasm(uint8_t *buf, unsigned len, int &append)
640{
641 etiss::instr::BitArray mainba(len * 8);
642 etiss::instr::Buffer buffer(mainba.intCount());
643
644 memcpy(buffer.internalBuffer(), buf, len);
645 mainba.set_value(buffer.data());
646
647 // TODO implement propper instruction selection with append requests is neccessary
648
650
651 if (vis == 0)
652 return "UNKNOWN";
653
654 etiss::instr::InstructionSet *is = vis->get(len * 8);
655
656 if (is == 0)
657 return "UNKNOWN";
658
659 etiss::instr::Instruction *instr = is->resolve(mainba);
660
661 if (instr == 0)
662 return "UNKNOWN";
663
664 return instr->printASM(mainba);
665}
666
667} // namespace etiss
contains neccesary interfaces for instruction translation.
contains container classes to store instruction definitions + translation functions and build a trans...
JIT compiler interface definition.
#define ETISS_DEBUG
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
if(__y==0) return __x
static __inline__ uint64_t
Definition arm_cde.h:31
static __inline__ uint8_t
Definition arm_mve.h:323
#define unlikely(x)
Definition types.h:36
uint8_t etiss_uint8
Definition types.h:49
virtual std::string getIncludePath()
returns a path that will be used to look up header files
Definition CPUArch.cpp:118
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.
Definition CPUArch.cpp:158
std::string getName() const
returns the name of this architecture.
Definition CPUArch.h:138
equivalent of a translated instruction
Definition CodePart.h:540
CodeSet & getCodeSet()
Definition CodePart.h:547
A list of CodeSets.
Definition CodePart.h:532
void toCode(std::stringstream &out, const std::string &funcname, std::set< std::string > *fileglobalcode)
Definition CodePart.cpp:108
std::set< std::string > & functionglobalCode()
Definition CodePart.h:567
void reserve(int num)
Definition CodePart.h:558
etiss::uint64 endaddress_
Definition CodePart.h:573
std::set< std::string > & fileglobalCode()
Definition CodePart.h:566
etiss::uint64 startindex_
Definition CodePart.h:572
Line & append(etiss::uint64 addr)
Definition CodePart.h:560
T get(const std::string &key, T default_, bool *default_used=0)
template function to read the value of a configuration key.
Definition Misc.h:312
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
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...
base plugin class that provides access to different plugin functions if present
Definition Plugin.h:38
TranslationPlugin * getTranslationPlugin()
Definition Plugin.h:86
allows to add code to the translation of instructions
Definition Plugin.h:222
virtual void initCodeBlock(etiss::CodeBlock &) const
called before instructions are translated for the code block
Definition Plugin.cpp:55
virtual void finalizeInstrSet(etiss::instr::ModedInstructionSet &) const
called after all instructions have been added to allow last changes
Definition Plugin.cpp:54
virtual void finalizeCodeBlock(etiss::CodeBlock &) const
called after all instructions have been translated for the code block
Definition Plugin.cpp:56
virtual void initInstrSet(etiss::instr::ModedInstructionSet &) const
called to add instructions to the instruction set
Definition Plugin.cpp:53
std::string pointerCode
Definition Plugin.h:248
virtual void * getPluginHandle()
called to get the handle that is available in translated code via getPoinerCode()....
Definition Plugin.cpp:58
std::string disasm(uint8_t *buf, unsigned len, int &append)
etiss::instr::ModedInstructionSet * mis_
etiss::JIT *const jit_
Definition Translation.h:88
uint64_t tblockcount
countes translated blocks. needed to guarantee unique block function names
std::list< std::shared_ptr< etiss::Plugin > > & plugins_
Definition Translation.h:89
size_t plugins_array_size_
Definition Translation.h:94
etiss::TranslationPlugin ** plugins_array_
Definition Translation.h:92
void unloadBlocks(etiss::uint64 startindex=0, etiss::uint64 endindex=((etiss::uint64)((etiss::int64) -1)))
etiss::CPUArch *const arch_
Definition Translation.h:87
void ** plugins_handle_array_
Definition Translation.h:93
std::unordered_map< etiss::uint64, std::list< BlockLink * > > blockmap_
ETISS_CPU & cpu_
Definition Translation.h:91
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...
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)
ETISS_System & system_
Definition Translation.h:90
stores a bit vector
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.
Definition Instruction.h:46
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 * 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_
forwards: include/jit/*
Definition Benchmark.h:17
std::string jitFiles()
Get ETISS JIT files path.
Definition Misc.cpp:563
std::vector< std::string > jitExtLibPaths()
Get ETISS JIT external path.
Definition Misc.cpp:592
std::string toString(const T &val)
conversion of type T to std::string.
Definition Misc.h:133
static uint64_t genTranslationId()
etiss::int32(* ExecBlockCall)(ETISS_CPU *cpu, ETISS_System *system, void **plugin_pointers)
Definition Translation.h:18
static std::enable_if< len==pos, void >::type call_initCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
std::vector< std::string > jitExtLibraries()
Get ETISS JIT external libraries.
Definition Misc.cpp:576
std::vector< std::string > jitExtHeaders()
Get ETISS JIT external headers.
Definition Misc.cpp:568
std::vector< std::string > jitExtHeaderPaths()
Get ETISS JIT external path.
Definition Misc.cpp:584
@ ERROR
Definition Misc.h:85
static void call_initCodeBlock_ul(etiss::TranslationPlugin **ca, CodeBlock &cb)
Configuration & cfg()
Definition Misc.cpp:548
static void call_finalizeCodeBlock_ul(etiss::TranslationPlugin **ca, CodeBlock &cb)
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:94
static std::enable_if< len==pos, void >::type call_finalizeCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
basic cpu state structure needed for execution of any cpu architecture.
Definition CPU.h:51
etiss_uint32 mode
instruction set mode of the processor
Definition CPU.h:71
memory access and time synchronization functions.
Definition System.h:40
void * handle
custom handle that will be passed to the functions of this structure
Definition System.h:78
etiss_int32(* dbg_read)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug read
Definition System.h:66