ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Translation.cpp
Go to the documentation of this file.
1/*
2
3 @copyright
4
5 <pre>
6
7 Copyright 2018 Infineon Technologies AG
8
9 This file is part of ETISS tool, see <https://github.com/tum-ei-eda/etiss>.
10
11 The initial version of this software has been created with the funding support by the German Federal
12 Ministry of Education and Research (BMBF) in the project EffektiV under grant 01IS13022.
13
14 Redistribution and use in source and binary forms, with or without modification, are permitted
15 provided that the following conditions are met:
16
17 1. Redistributions of source code must retain the above copyright notice, this list of conditions and
18 the following disclaimer.
19
20 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
21 and the following disclaimer in the documentation and/or other materials provided with the distribution.
22
23 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
24 or promote products derived from this software without specific prior written permission.
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
27 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
28 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
29 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34
35 </pre>
36
37 @author Chair of Electronic Design Automation, TUM
38
39 @version 0.1
40
41*/
42
43#include "etiss/Translation.h"
44#include <mutex>
45
46namespace etiss
47{
48
49BlockLink::BlockLink(etiss::uint64 start, etiss::uint64 end, ExecBlockCall execBlock, std::shared_ptr<void> lib)
50 : start(start), end(end), execBlock(execBlock), jitlib(lib)
51{
52 refcount = 0;
53 next = 0;
54 branch = 0;
55 valid = true;
56}
57
65
66template <unsigned len, unsigned pos>
67static typename std::enable_if<len == pos, void>::type call_initCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
68{
69 return;
70}
71template <unsigned len, unsigned pos>
72static typename std::enable_if<len != pos, void>::type call_initCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
73{
74 ca[pos]->initCodeBlock(cb);
75 call_initCodeBlock<len, pos + 1>(ca, cb);
76}
77
78template <unsigned len, unsigned pos>
79static typename std::enable_if<len == pos, void>::type call_finalizeCodeBlock(etiss::TranslationPlugin **ca,
80 CodeBlock &cb)
81{
82 return;
83}
84template <unsigned len, unsigned pos>
85static typename std::enable_if<len != pos, void>::type call_finalizeCodeBlock(etiss::TranslationPlugin **ca,
86 CodeBlock &cb)
87{
88 ca[pos]->finalizeCodeBlock(cb);
89 call_finalizeCodeBlock<len, pos + 1>(ca, cb);
90}
91
93{
94 size_t pos = 0;
95 while (ca[pos] != nullptr)
96 {
97 ca[pos++]->initCodeBlock(cb);
98 }
99}
101{
102 size_t pos = 0;
103 while (ca[pos] != nullptr)
104 {
105 ca[pos++]->finalizeCodeBlock(cb);
106 }
107}
108
110{
111 static std::mutex mu;
112 static uint64_t id = 0;
113 std::lock_guard<std::mutex> lock(mu);
114 return id++;
115}
116
117Translation::Translation(std::shared_ptr<etiss::CPUArch> &arch, std::shared_ptr<etiss::JIT> &jit,
118 std::list<std::shared_ptr<etiss::Plugin>> &plugins, ETISS_System &system, ETISS_CPU &cpu)
119 : archptr_(arch)
120 , jitptr_(jit)
121 , arch_(archptr_.get())
122 , jit_(jitptr_.get())
123 , plugins_(plugins)
124 , system_(system)
125 , cpu_(cpu)
126 , plugins_array_(0)
127 , plugins_handle_array_(0)
128 , mis_(0)
129#if ETISS_TRANSLATOR_STAT
130 , next_count_(0)
131 , branch_count_(0)
132 , miss_count_(0)
133#endif
134 , id(genTranslationId())
135{
136 tblockcount = 0;
137}
138
140{
141 unloadBlocks(0, (uint64_t)((int64_t)-1));
142 delete[] plugins_array_;
143 delete[] plugins_handle_array_;
144 delete mis_;
145}
146
148{
149 delete[] plugins_array_;
150 plugins_array_ = 0;
151 delete[] plugins_handle_array_;
153 delete mis_;
154 mis_ = 0;
155
156 if (arch_ == nullptr)
157 return nullptr;
158
159 if (jit_ == nullptr)
160 return nullptr;
161
162 // First plugin to more to tmpl list is the architecture plugin
164
165 std::vector<etiss::TranslationPlugin *> tmpl;
166
167 tmpl.push_back(arch_);
168
169 // Followed by all plugins, which are of type translation plugin
170 for (auto iter = plugins_.begin(); iter != plugins_.end(); iter++)
171 {
172 etiss::Plugin *p = iter->get();
173 if (p != nullptr)
174 {
176 if (tp != nullptr)
177 {
178 tmpl.push_back(tp);
179 }
180 }
181 }
182
183 // Build up the plugin lists
184 plugins_array_ = new etiss::TranslationPlugin *[tmpl.size() + 1];
185 plugins_array_[tmpl.size()] = nullptr;
186 plugins_handle_array_ = new void *[tmpl.size()];
187 plugins_array_size_ = tmpl.size();
188
189 for (size_t i = 0; i < tmpl.size(); i++)
190 {
191 plugins_array_[i] = tmpl[i];
193 /* During execution of each code block, the list plugin_handle_, which
194 returned by the function init, is passed again as parameter with name
195 plugin_pointers
196 -> plugin_pointers is the name of the list of translation plugin in the
197 generated c-code of all code blocks
198 */
199 plugins_array_[i]->pointerCode = std::string("(plugin_pointers[") + toString(i) + "])";
200 }
201
202 // Call the function initInstrSet for all translation plugins
203 for (size_t i = 0; i < tmpl.size(); i++)
204 {
206 }
207 // Call the function finalizeInstrSet( for all translation plugins
208 for (int i = (int)tmpl.size() - 1; i >= 0; i--)
209 {
211 }
212
214
215 if (!mis_->compile())
216 {
217 etiss::log(etiss::ERROR, "Failed to compile instruction set");
218 delete[] plugins_array_;
219 plugins_array_ = 0;
220 delete[] plugins_handle_array_;
222 delete mis_;
223 mis_ = 0;
224 }
225
226 // Builds the function for function pointer plugins_initCodeBlock_ It calls_initCodeBlock functions of all
227 // translation plugins Builds the functions plugins_finalizeCodeBlock_ It calls_finalizeCodeBlock functions of all
228 // translation plugins
229 switch (plugins_array_size_)
230 {
231 case 1:
232 plugins_initCodeBlock_ = &(call_initCodeBlock<1, 0>);
233 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<1, 0>);
234 break;
235 case 2:
236 plugins_initCodeBlock_ = &(call_initCodeBlock<2, 0>);
237 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<2, 0>);
238 break;
239 case 3:
240 plugins_initCodeBlock_ = &(call_initCodeBlock<3, 0>);
241 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<3, 0>);
242 break;
243 case 4:
244 plugins_initCodeBlock_ = &(call_initCodeBlock<4, 0>);
245 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<4, 0>);
246 break;
247 case 5:
248 plugins_initCodeBlock_ = &(call_initCodeBlock<5, 0>);
249 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<5, 0>);
250 break;
251 case 6:
252 plugins_initCodeBlock_ = &(call_initCodeBlock<6, 0>);
253 plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<6, 0>);
254 break;
255 default:
258 }
259
261}
262
263BlockLink *Translation::getBlock(BlockLink *prev, const etiss::uint64 &instructionindex)
264{
265
266 std::string error;
267
268 if (prev != 0 && !prev->valid)
269 {
270 prev = 0;
271 }
272
273 // search block in cache
274 std::list<BlockLink *> &list = blockmap_[instructionindex >> 9];
275 for (std::list<BlockLink *>::iterator iter = list.begin(); iter != list.end();) // iter++ moved into block
276 {
277 BlockLink *iterbl = (*iter);
278 if (iterbl != 0)
279 {
280 if (iterbl->valid) // check for valid block
281 {
282 if (iterbl->start <= instructionindex && iterbl->end > instructionindex)
283 {
284 if (prev != 0)
285 {
286 if (prev->end == iterbl->start)
287 {
288 BlockLink::updateRef(prev->next, iterbl);
289 }
290 else
291 {
292 BlockLink::updateRef(prev->branch, iterbl);
293 }
294 }
295 return *iter;
296 }
297 iter++;
298 }
299 else // cleanup
300 {
301 BlockLink::updateRef(iterbl->next, 0);
302 BlockLink::updateRef(iterbl->branch, 0);
303 list.erase(iter++);
305 iterbl); // remove reference of map // prev remains valid because this blocklink needs to be invalid
306 continue;
307 }
308 }
309 }
310
311 // generate block
312
313 std::string blockfunctionname;
314 {
315 std::stringstream ss;
316 ss << "_t" << id << "c" << tblockcount++ << "_block_" << instructionindex;
317 blockfunctionname = ss.str();
318 }
319
320 CodeBlock block(instructionindex);
321
322 #ifdef ETISS_USE_COREDSL_COVERAGE
323 block.fileglobalCode().insert("#define ETISS_USE_COREDSL_COVERAGE");
324 #endif
325
326 block.fileglobalCode().insert("#include \"etiss/jit/CPU.h\"\n"
327 "#include \"etiss/jit/System.h\"\n"
328 "#include \"etiss/jit/libresources.h\"\n"
329 "#include \"etiss/jit/libsemihost.h\"\n"
330 "#include \"etiss/jit/ReturnCode.h\"\n"
331 "#include \"etiss/jit/libCSRCounters.h\"\n");
332
333 for(auto &it: jitExtHeaders()){
334 if(it != "") block.fileglobalCode().insert("#include \"" + it + "\"\n");
335 }
336
337 block.functionglobalCode().insert("if (cpu->mode != " + toString(cpu_.mode) +
338 ") return ETISS_RETURNCODE_RELOADCURRENTBLOCK;");
339
341
342 etiss::int32 transerror = translateBlock(block);
343
344 if (transerror != ETISS_RETURNCODE_NOERROR)
345 {
346 etiss::log(etiss::ERROR, "Failed to translate block");
347 return nullptr;
348 }
349
351
352 std::string code;
353 {
354 std::stringstream ss;
355 block.toCode(ss, blockfunctionname, nullptr);
356 code = ss.str();
357 }
358
359 // various includes
360 std::set<std::string> headers;
361 headers.insert(etiss::jitFiles());
362 headers.insert(arch_->getIncludePath());
363 for(auto & it: jitExtHeaderPaths()){
364 if(it != "") headers.insert(it);
365 }
366
367 std::set<std::string> libloc;
368 libloc.insert(arch_->getIncludePath());
369 libloc.insert(etiss::cfg().get<std::string>("etiss_path", "./"));
370 libloc.insert(etiss::jitFiles());
371 libloc.insert(etiss::jitFiles() + "/etiss/jit");
372 for(auto & it: jitExtLibPaths()){
373 if(it != "") libloc.insert(etiss::jitFiles() + it);
374 }
375
376 std::set<std::string> libs;
377 //libs.insert("ETISS");
378 libs.insert("resources");
379 libs.insert("semihost");
380 libs.insert("CSRCounters");
381 for(auto & it: jitExtLibraries()){
382 if(it != "") libs.insert(it);
383 }
384 /* DEBUG HELPER: write code files to work directory
385 {
386 static unsigned count = 0;
387 std::stringstream ss;
388 ss << "code" << ++count;
389 std::ofstream out;
390 out.open(ss.str().c_str());
391 out << code;
392 std::cout << "Code file " << count << std::endl;
393 }
394 */
395#ifndef ETISS_DEBUG
396#define ETISS_DEBUG 1
397#endif
398 // compile library
399 void *funcs =
400 jit_->translate(code, headers, libloc, libs, error, etiss::cfg().get<bool>("jit.debug", ETISS_DEBUG) != 0);
401
402 if (funcs == 0)
403 {
404 etiss::log(etiss::ERROR, error);
405 return 0;
406 }
407
408 // wrap library handle for cleanup
409 auto local_jit = jit_;
410 std::shared_ptr<void> lib(funcs, [local_jit](void *p) { local_jit->free(p); });
411
412 // check function/library handle
413 if (lib.get() != 0)
414 {
415 // std::cout<<"blockfunctionname:"<<blockfunctionname<<std::endl;
416 ExecBlockCall execBlock = (ExecBlockCall)jit_->getFunction(lib.get(), blockfunctionname.c_str(), error);
417 if (execBlock != 0)
418 {
419 BlockLink *nbl = new BlockLink(block.startindex_, block.endaddress_, execBlock, lib);
420 uint64 ii9 = instructionindex >> 9;
421 do
422 {
423 blockmap_[ii9].push_back(nbl);
424 BlockLink::incrRef(nbl); // map holds a reference
425 ii9++;
426 } while ((ii9 << 9) < block.endaddress_);
427
428 if (prev != 0)
429 {
430 if (nbl->start == prev->end)
431 {
432 BlockLink::updateRef(prev->next, nbl);
433 }
434 else
435 {
436 BlockLink::updateRef(prev->branch, nbl);
437 }
438 }
439 return nbl;
440 }
441 else
442 {
443 etiss::log(etiss::ERROR, std::string("Failed to acquire function pointer from compiled library:") + error);
444 return 0;
445 }
446 }
447
448 return 0;
449}
453{
454 cb.endaddress_ = cb.startindex_;
455
457
458 context.cf_delay_slot_ = 0;
459 context.force_block_end_ = false;
460
461 unsigned count = 0;
462 const unsigned maxcount = etiss::cfg().get<unsigned>("etiss.max_block_size", 100);
463 cb.reserve(maxcount);
464
466
467 if (vis_ == nullptr)
468 {
469 return etiss::RETURNCODE::GENERALERROR;
470 }
471
472 etiss::instr::BitArray mainba(vis_->width_);
474
475 do
476 {
477 context.force_append_next_instr_ = false;
478 context.force_block_end_ = false;
479 context.current_address_ = cb.endaddress_;
481 context.instr_width_fully_evaluated_ = true;
482 context.is_not_default_width_ = false;
483 context.instr_width_ = vis_->width_;
484
485 etiss::instr::BitArray errba(32, 0);
486
487 buffer = etiss::instr::Buffer(mainba.intCount());
488 // read instruction
489 etiss::int32 ret = (*system_.dbg_read)(system_.handle, cb.endaddress_, (etiss_uint8*)buffer.internalBuffer(), mainba.byteCount()); // read instruction
490 mainba.set_value(buffer.data());
491 if (ret == etiss::RETURNCODE::IBUS_READ_ERROR || ret == etiss::RETURNCODE::DBUS_READ_ERROR)
492 {
493 std::cout << "Instruction bus read error while translating!" << std::endl;
494 errba.set_value(etiss::RETURNCODE::IBUS_READ_ERROR);
495 // std::cout << "mainba.byteCount = " << mainba.byteCount() << std::endl;
496 auto instr = &vis_->getMain()->getInvalid();
497 CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
498 bool ok = instr->translate(errba, line.getCodeSet(), context);
499 if (unlikely(!ok)) {
500 return etiss::RETURNCODE::GENERALERROR;
501 }
502 cb.endaddress_ += mainba.byteCount(); // update end address
503 return etiss::RETURNCODE::NOERROR;
504 }
505 if (ret != etiss::RETURNCODE::NOERROR)
506 {
507 if (count == 0)
508 {
509 return ret; // empty block -> return error
510 }
511 else
512 {
513 break; // non empty block -> compile pending
514 }
515 }
516
517 arch_->compensateEndianess(&cpu_, mainba);
518 vis_->length_updater_(*vis_, context, mainba);
519
520 // continue reading instruction data if neccessary
521 if (unlikely(context.is_not_default_width_))
522 {
523 etiss::instr::BitArray *secba = nullptr;
524 do
525 {
526 if (secba)
527 delete secba;
528 secba = new etiss::instr::BitArray(context.instr_width_);
529
530 buffer = etiss::instr::Buffer(secba->intCount());
531 ret = (*system_.dbg_read)(system_.handle, cb.endaddress_, (etiss_uint8*)buffer.internalBuffer(), secba->byteCount()); // read instruction
532 secba->set_value(buffer.data());
533
534 if (ret != etiss::RETURNCODE::NOERROR)
535 {
536 if (count == 0)
537 {
538 delete secba;
539 return ret; // empty block -> return error
540 }
541 else
542 {
543 break; // non empty block -> compile pending
544 }
545 }
546 arch_->compensateEndianess(&cpu_, *secba);
547 vis_->length_updater_(*vis_, context, *secba);
548 } while (!context.instr_width_fully_evaluated_);
549
551 etiss::instr::InstructionSet *instrSet = vis_->get(secba->size());
552 if (unlikely(!instrSet))
553 {
554 errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
555 instr = &vis_->getMain()->getInvalid();
556 }
557 else
558 {
559 instr = instrSet->resolve(*secba);
560 if (unlikely(!instr))
561 {
562 errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
563 instr = &instrSet->getInvalid();
564 }
565 }
566 CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
567 bool ok = instr->translate(errba != etiss::instr::BitArray(32, 0) ? errba : *secba, line.getCodeSet(), context);
568 if (unlikely(!ok))
569 {
570 delete secba;
571 return etiss::RETURNCODE::GENERALERROR;
572 }
573 cb.endaddress_ += secba->byteCount(); // update end address
574 delete secba;
575 }
576 else
577 {
578 etiss::instr::InstructionSet *instrSet = vis_->getMain();
579 etiss::instr::Instruction *instr = instrSet->resolve(mainba);
580 if (unlikely(instr == 0))
581 {
582 errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
583 instr = &instrSet->getInvalid();
584 }
585 CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
586 bool ok = instr->translate(errba != etiss::instr::BitArray(32, 0) ? errba : mainba, line.getCodeSet(), context);
587 if (unlikely(!ok))
588 {
589 return etiss::RETURNCODE::GENERALERROR;
590 }
591 cb.endaddress_ += mainba.byteCount(); // update end address
592 }
593
594 count++;
595 } while ((count < maxcount && !context.force_block_end_) || context.force_append_next_instr_);
596
597 return etiss::RETURNCODE::NOERROR;
598}
599
601{
602 for (auto &entry:blockmap_)
603 {
604 entry.second.erase(std::remove_if(entry.second.begin(), entry.second.end(),
605 [](auto &bl)
606 {
607 bl->valid = false;
608 BlockLink::updateRef(bl->next, 0);
609 BlockLink::updateRef(bl->branch, 0);
610 BlockLink::decrRef(bl); // remove reference of map
611 return true;
612 }),
613 entry.second.end());
614 }
615 blockmap_.clear();
616}
617
618void Translation::unloadBlocks(etiss::uint64 startindex, etiss::uint64 endindex)
619{
620 // Hotfix: if everything needs to be deleted, new function unloadBlocksAll()
621 if (startindex == 0 && endindex == ((etiss::uint64)((etiss::int64)-1)))
622 {
624 return;
625 }
626
627 const etiss::uint64 startindexblock = startindex >> 9;
628 const etiss::uint64 endindexblock = (endindex >> 9) + ((((endindex >> 9) << 9) == endindex) ? 0 : 1);
629 for (etiss::uint64 block = startindexblock; block < endindexblock; block++)
630 {
631 if (blockmap_.empty())
632 break;
633 auto entry = blockmap_.find(block);
634 if (entry != blockmap_.end())
635 {
636 for (std::list<BlockLink *>::iterator iter = entry->second.begin(); iter != entry->second.end();)
637 {
638 BlockLink *bl = *iter;
639 if (bl->start < endindex || bl->end > startindex)
640 {
641 bl->valid = false;
644 entry->second.erase(iter++);
645 BlockLink::decrRef(bl); // remove reference of map
646 }
647 else
648 {
649 iter++;
650 }
651 }
652 if (entry->second.empty())
653 blockmap_.erase(entry);
654 }
655 }
656}
657
658std::string Translation::disasm(uint8_t *buf, unsigned len, int &append)
659{
660 etiss::instr::BitArray mainba(len * 8);
661 etiss::instr::Buffer buffer(mainba.intCount());
662
663 memcpy(buffer.internalBuffer(), buf, len);
664 mainba.set_value(buffer.data());
665
666 // TODO implement propper instruction selection with append requests is neccessary
667
669
670 if (vis == 0)
671 return "UNKNOWN";
672
673 etiss::instr::InstructionSet *is = vis->get(len * 8);
674
675 if (is == 0)
676 return "UNKNOWN";
677
678 etiss::instr::Instruction *instr = is->resolve(mainba);
679
680 if (instr == 0)
681 return "UNKNOWN";
682
683 return instr->printASM(mainba);
684}
685
686} // namespace etiss
etiss_uint64 uint64
Definition 386-GCC.h:82
#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:74
uint8_t etiss_uint8
Definition types.h:87
virtual std::string getIncludePath()
returns a path that will be used to look up header files
Definition CPUArch.cpp:150
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:188
std::string getName() const
returns the name of this architecture.
Definition CPUArch.h:184
equivalent of a translated instruction
Definition CodePart.h:578
CodeSet & getCodeSet()
Definition CodePart.h:585
A list of CodeSets.
Definition CodePart.h:570
void toCode(std::stringstream &out, const std::string &funcname, std::set< std::string > *fileglobalcode)
Definition CodePart.cpp:146
std::set< std::string > & functionglobalCode()
Definition CodePart.h:605
void reserve(int num)
Definition CodePart.h:596
etiss::uint64 endaddress_
Definition CodePart.h:611
std::set< std::string > & fileglobalCode()
Definition CodePart.h:604
etiss::uint64 startindex_
Definition CodePart.h:610
Line & append(etiss::uint64 addr)
Definition CodePart.h:598
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:349
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:77
TranslationPlugin * getTranslationPlugin()
Definition Plugin.h:125
allows to add code to the translation of instructions
Definition Plugin.h:262
virtual void initCodeBlock(etiss::CodeBlock &) const
called before instructions are translated for the code block
Definition Plugin.cpp:93
virtual void finalizeInstrSet(etiss::instr::ModedInstructionSet &) const
called after all instructions have been added to allow last changes
Definition Plugin.cpp:92
virtual void finalizeCodeBlock(etiss::CodeBlock &) const
called after all instructions have been translated for the code block
Definition Plugin.cpp:94
virtual void initInstrSet(etiss::instr::ModedInstructionSet &) const
called to add instructions to the instruction set
Definition Plugin.cpp:91
std::string pointerCode
Definition Plugin.h:288
virtual void * getPluginHandle()
called to get the handle that is available in translated code via getPoinerCode()....
Definition Plugin.cpp:96
std::string disasm(uint8_t *buf, unsigned len, int &append)
etiss::instr::ModedInstructionSet * mis_
etiss::JIT *const jit_
uint64_t tblockcount
countes translated blocks. needed to guarantee unique block function names
std::list< std::shared_ptr< etiss::Plugin > > & plugins_
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...
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_
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:92
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_
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition Benchmark.h:53
std::string jitFiles()
Get ETISS JIT files path.
Definition Misc.cpp:592
std::vector< std::string > jitExtLibPaths()
Get ETISS JIT external path.
Definition Misc.cpp:618
std::string toString(const T &val)
conversion of type T to std::string.
Definition Misc.h:174
static uint64_t genTranslationId()
etiss::int32(* ExecBlockCall)(ETISS_CPU *cpu, ETISS_System *system, void **plugin_pointers)
Definition Translation.h:57
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:604
std::vector< std::string > jitExtHeaders()
Get ETISS JIT external headers.
Definition Misc.cpp:597
std::vector< std::string > jitExtHeaderPaths()
Get ETISS JIT external path.
Definition Misc.cpp:611
@ ERROR
Definition Misc.h:127
static void call_initCodeBlock_ul(etiss::TranslationPlugin **ca, CodeBlock &cb)
Configuration & cfg()
Definition Misc.cpp:577
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:125
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:89
etiss_uint32 mode
instruction set mode of the processor
Definition CPU.h:109
memory access and time synchronization functions.
Definition System.h:78
void * handle
custom handle that will be passed to the functions of this structure
Definition System.h:116
etiss_int32(* dbg_read)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug read
Definition System.h:104