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
Instruction.cpp
Go to the documentation of this file.
1
52#include "etiss/Instruction.h"
53
54#include <sstream>
55#include <cassert>
56#include <cmath>
57#if ETISS_USE_BYTESWAP_H
58#include <byteswap.h>
59#endif
60
61namespace etiss
62{
63
64namespace instr
65{
66
67typedef BitArray::size_type size_type;
68
70{
71 return static_cast<char *>(static_cast<void *>(d_));
72}
74{
75 return intcount_ * sizeof(I);
76}
77
78void Buffer::recoverFromEndianness(unsigned alignment, endian_t endianness)
79{
80 if (intcount_ <= 0)
81 return;
82
83#if ETISS_USE_BYTESWAP_H
84 if (sizeof(I) == alignment)
85 {
86 if (endianness != getEndianness())
87 {
88 if (sizeof(I) == 4)
89 {
90 for (unsigned i = 0; i < intcount_; i++)
91 {
92 d_[i] = __bswap_32(d_[i]);
93 }
94 }
95 else
96 {
97 // TODO
98 etiss::log(etiss::FATALERROR, "bit swap notimplemented for this case", alignment, endianness, sizeof(I),
100 }
101 }
102 }
103 else
104 {
105 etiss::log(etiss::FATALERROR, "bit swap notimplemented for this case", alignment, endianness, sizeof(I),
107 }
108#else
109
110 if (sizeof(I) == alignment)
111 {
112 if (endianness != getEndianness())
113 {
114 for (unsigned i = 0; i < intcount_; i++)
115 {
116 for (unsigned j = 0; j < (sizeof(I) >> 1); j++)
117 {
118 int8_t tmp = ((int8_t *)&(d_[i]))[j];
119 ((int8_t *)&(d_[i]))[j] = ((int8_t *)&(d_[i]))[sizeof(I) - 1 - j];
120 ((int8_t *)&(d_[i]))[sizeof(I) - 1 - j] = tmp;
121 }
122 }
123 }
124 }
125 else
126 {
127 etiss::log(etiss::FATALERROR, "bit swap notimplemented for this case", alignment, endianness, sizeof(I),
129 }
130
131#endif
132}
133
134unsigned BitArray::byteCount() const {
135 unsigned mod = size() % (8);
136 unsigned ret = (size() - mod) / (8);
137 if (mod > 0) ret++;
138 return ret;
139}
140unsigned BitArray::intCount() const {
141 unsigned mod = size() % (sizeof(I) * 8);
142 unsigned ret = (size() - mod) / (sizeof(I) * 8);
143 if (mod > 0) ret++;
144 return ret;
145}
146
147std::vector<BitArray> BitArray::permutate(const BitArray& input, std::vector<size_type> indexes)
148{
149 std::vector<BitArray> results{input};
150 int count = 0;
151 for(const auto& i : indexes){
152 for(int j=0; j<(1<<count); j++){
153 results.push_back(results[j]);
154 results[j].flip(i);
155 results.push_back(results[j]);
156 }
157 results.erase(results.begin(), results.begin() + (1<<count));
158 count++;
159 }
160 return results;
161}
162
163void BitArray::set_value(size_type width, unsigned long value){
164 BitArray b(width, value);
165 *this = b;
166}
167
168void BitArray::set_value(unsigned long value){
169 set_value(size(), value);
170}
171
173{
174 // shift the bits and resize it accordingly
175 BitArray ret = *this;
176 ret >>= start;
177 ret.resize(end-start+1);
178 return ret;
179}
180
181void BitArray::set_range(unsigned long val, size_type end, size_type start){
182 auto len = end - start + 1;
183 BitArray range(len, val);
184 for(size_type i = 0; i < len; ++i)
185 (*this)[i+start] = range[i];
186}
187
188std::string BitArray::to_string() const
189{
190 std::string s;
191 boost::to_string(*this, s);
192 return s;
193}
194
195BitArrayRange::BitArrayRange(unsigned endindex_included, unsigned startindex_included)
196 : startpos(startindex_included), endpos(endindex_included) {}
197
199{
200 assert(ba.size() >= (endpos - startpos + 1) && "BitArrayRange outside of BitArray");
201 auto range = ba.get_range(endpos, startpos);
202 return range.to_ulong();
203}
204
206{
207 assert(ba.size() >= (endpos - startpos + 1) && "BitArrayRange outside of BitArray");
208 ba.set_range(val, endpos, startpos);
209}
210
211BitArray::size_type BitArrayRange::start()
212{
213 return startpos;
214}
215
216BitArray::size_type BitArrayRange::end()
217{
218 return endpos;
219}
220
221OPCode::OPCode(const BitArray &code, const BitArray &mask) : code_(code & mask), mask_(mask)
222{
223 if (code_.size() != mask_.size())
224 {
225 etiss::log(etiss::ERROR, "etiss::instr::OPCode constructed with code and mask of different widths");
226 throw std::runtime_error("etiss::instr::OPCode constructed with code and mask of different widths");
227 }
228#if DEBUG
229 if (!((code & mask) == code))
230 {
231 etiss::log(etiss::WARNING, "etiss::instr::OPCode constructed with mismatched code and mask");
232 }
233#endif
234}
235
236OPCode::OPCode(const OPCode &cpy) : code_(cpy.code_), mask_(cpy.mask_) {}
237
238bool OPCode::operator<(const OPCode &o) const
239{
240 if (mask_ != o.mask_)
241 return mask_ < o.mask_;
242 if (code_ != o.code_)
243 return code_ < o.code_;
244 return false;
245}
246
247bool less::operator()(const OPCode *const &o1, const OPCode *const &o2) const
248{
249
250 if ((o1 == 0) || (o2 == 0))
251 {
252 if (o2 != 0)
253 return true;
254 etiss_log(FATALERROR, "null pointer passed to etiss::instr::less");
255 return false;
256 }
257
258 return (*o1) < (*o2);
259}
260
261unsigned &InstructionContext::ufield(std::string name)
262{
263 return ufields_[name];
264}
265
266Instruction::Instruction(const OPCode &opc, const std::string &name)
267 : builtinGroups_(0), printer_(printASMSimple), width(opc.code_.size()), opc_(opc), name_(name)
268{
269}
271{
272 std::stringstream ss;
273 ss << instr.name_ << " # 0x" << ba << " [UNKNOWN PARAMETERS]";
274 return ss.str();
275}
276
277std::string Instruction::print(std::string indent, I pos, unsigned pfillwidth, bool printunused)
278{
279 std::stringstream ss;
280 ss.fill('0');
281 ss << indent << "@0x" << std::hex << std::setw(pfillwidth) << pos << std::dec << " Instruction: " << name_ << "\n";
282 return ss.str();
283}
284bool Instruction::addCallback(std::function<bool(BitArray &, etiss::CodeSet &, InstructionContext &)> callback,
285 uint32_t builtinGroups, const std::set<uint32_t> &groups)
286{
287
288 if ((builtinGroups_ & builtinGroups) != 0)
289 {
290 etiss::log(etiss::VERBOSE, "cannot add instruction translation callback due to overlapping builtin group",
291 *this);
292 return false;
293 }
294 for (auto iter = groups.begin(); iter != groups.end(); iter++)
295 {
296 if (groups_.find(*iter) != groups_.end())
297 {
298 etiss::log(etiss::VERBOSE, "cannot add instruction translation callback due to overlapping group", *this);
299 return false;
300 }
301 }
302
303 if (!callback)
304 {
305 etiss::log(etiss::VERBOSE, "empty instruction translation callback", *this);
306 return false;
307 }
308
309 builtinGroups_ |= builtinGroups;
310 for (auto iter = groups.begin(); iter != groups.end(); iter++)
311 {
312 groups_.insert(*iter);
313 }
314
315 callbacks_.push_back(std::tuple<std::function<bool(BitArray &, etiss::CodeSet &, InstructionContext &)>, uint32_t,
316 std::set<uint32_t>>(callback, builtinGroups, groups));
317
318 return true;
319}
321{
322 bool ok = true;
323 for (auto iter = callbacks_.begin(); iter != callbacks_.end(); iter++)
324 {
325 ok = ok & std::get<0>(*iter)(ba, cs, context);
326 }
327 return ok;
328}
329
334std::set<uint32_t> &Instruction::presentGroups()
335{
336 return groups_;
337}
338
340{
341 return printer_(ba, *this);
342}
343
344void Instruction::setASMPrinter(std::function<std::string(BitArray &, Instruction &)> printer)
345{
346 printer_ = printer;
347 if (!printer_)
349}
350
351InstructionSet::InstructionSet(VariableInstructionSet &parent, unsigned width, const std::string &name, unsigned c_size)
352 : parent_(parent), name_(name), width_(width), chunk_size(c_size), root_(nullptr), invalid(width, -1, -1, "INVALID")
353{
354
355}
356
358{
359 auto iter = instrmap_.begin();
360 // delete instructions
361 while (iter != instrmap_.end())
362 {
363 Instruction *i = iter->second;
364 instrmap_.erase(iter);
365 iter = instrmap_.begin();
366 delete i;
367 }
368 for(unsigned int i = 0; i < width_ / chunk_size; i++)
369 delete[] root_[i];
370 delete root_;
371}
372
374{
375 auto f = instrmap_.find(&key);
376 if (f != instrmap_.end())
377 {
378 return f->second;
379 }
380 return nullptr;
381}
382Instruction &InstructionSet::open(const OPCode &key, const std::string &name)
383{
384 Instruction *ret = get(key);
385 if (ret != nullptr)
386 return *ret;
387 ret = create(key, name);
388#if DEBUG
389 if (ret == nullptr)
390 {
391 etiss_log(FATALERROR, "should not happen");
392 }
393#endif
394 return *ret;
395}
396Instruction *InstructionSet::create(const OPCode &key, const std::string &name)
397{
398 auto f = instrmap_.find(&key);
399 if (f != instrmap_.end())
400 {
401 return nullptr;
402 }
403 Instruction *ret = new Instruction(key, name);
404 if (instrmap_.insert(std::pair<const OPCode *, Instruction *>(&ret->opc_, ret)).second == false)
405 {
406 etiss::log(ERROR, "Failed to add instruction to instrmap_.", name, *this);
407 delete ret;
408 return nullptr;
409 }
410 return ret;
411}
412
414{
415 delete root_; // cleanup
416
417 root_ = new Node*[width_ / chunk_size](); // number of groups = width_ / chunk_size
418
419 bool ok = true;
420
421 std::vector<size_type> indexes;
422 for (const auto& op2instr : instrmap_){ // iterate through all instructions
423 Instruction* inst = op2instr.second; // current instruction to be assigned
424 BitArray code = op2instr.first->code_; // opcode of the current instruction
425 BitArray mask = op2instr.first->mask_; // mask of the opcode
426
427 // iterate through chunks and permutate chunks. then put them into nodes
428 for (size_type i = 0; i < mask.size() / chunk_size; ++i){
429 auto chunk_bits_code = code.get_range((i+1)*chunk_size-1, i*chunk_size); // ith chunk of the opcode
430 auto chunk_bits_mask = mask.get_range((i+1)*chunk_size-1, i*chunk_size); // ith chunk of the mask
431
432 indexes.clear();
433 for (size_type j = 0; j < chunk_bits_mask.size(); ++j)
434 if (!chunk_bits_mask[j]) indexes.push_back(j); // these indexed should be permutated since
435 // they dont have associated mask bit
436
437 if(!(root_[i])) // not initialized
438 root_[i] = new Node[(int)std::pow(2, chunk_size)]; // each group has 2^(chunksize) nodes
439
440 auto permutated_chunk_codes = BitArray::permutate(chunk_bits_code, indexes); // put permutated codes
441
442 for(const auto& permutated_chunk : permutated_chunk_codes){
443 auto val = permutated_chunk.to_ulong(); // index of the node based on the value of the chunk
444 root_[i][val].insert(inst); // assign the current instruction to the associated node
445 }
446 }
447 }
448 return ok;
449}
450
452{
453 std::set<Instruction*> results;
454 for (size_type i = 0; i < instr.size() / chunk_size; ++i){ // divide the incoming bitarray into chunks
455 auto chunk_bits_code = instr.get_range((i+1)*chunk_size-1, i*chunk_size); // get ith chunk
456
457 auto val = chunk_bits_code.to_ulong(); // the value chunk is evaluated to,
458 // which is also the index of the associated node
459 auto instrs_in_node = root_[i][val]; // val'th node
460
461 if(i==0) results = instrs_in_node;
462 else{ // intersect all the associated nodes, the result will be the decoded instruction
463 std::set<Instruction*> results_o;
464 std::set_intersection(results.begin(), results.end(), // intersect the ith node with the
465 instrs_in_node.begin(), instrs_in_node.end(), // current results
466 std::inserter(results_o, results_o.begin())); // put overlapped instructions to results_o
467 results = results_o; // write the overlapped instructions to results
468 }
469 }
470
471 if(results.empty()) return nullptr; // there is no overlapped instruction after the decoding
472 else if(results.size() == 1) return *(results.begin()); // instruction is found succesfully
473 else{
474 // sometimes an instruction can be a subset of another instruction and hence the
475 // algorithm can find multiple instruction. In such cases, it is returning the parent
476 // instruction by simply returning the instrucion whose opcode is the longest,
477 // i.e mask has the most 1-bits.
478 auto longest = std::max_element(results.begin(), results.end(),
479 [](const Instruction* lhs, const Instruction* rhs) { return lhs->opc_.mask_.count() < rhs->opc_.mask_.count();});
480 return *longest;
481 }
482}
483
484std::string InstructionSet::print(std::string prefix, bool printunused)
485{
486 if (root_ != nullptr)
487 {
488 std::stringstream ss;
489 ss << prefix << name_ << "[" << width_ << "]:\n";
490 return ss.str();
491 }
492 else
493 {
494 return "EMPTY\n";
495 }
496}
497
502
503void InstructionSet::foreach (std::function<void(Instruction &)> func)
504{
505 for (auto iter = instrmap_.begin(); iter != instrmap_.end(); iter++)
506 {
507#if DEBUG
508 if (iter->second != nullptr)
509 {
510#endif
511 func(*iter->second);
512#if DEBUG
513 }
514 else
515 {
516 etiss::log(etiss::ERROR, "InstructionSet::getInvalid found a null pointer");
517 }
518#endif
519 }
520}
521
523{
524 return instrmap_.size();
525}
526
527VariableInstructionSet::VariableInstructionSet(ModedInstructionSet &parent, unsigned width, const std::string &archname)
528 : parent_(parent), width_(width), archname_(archname)
529{
530 length_updater_ = [this](VariableInstructionSet &, InstructionContext &con, BitArray &) {
531 con.is_not_default_width_ = false;
532 con.instr_width_ = width_;
533 };
534}
536{
537 // delete instruction set
538 for (auto iter = ismap_.begin(); iter != ismap_.end(); iter++)
539 {
540 delete iter->second;
541 }
542}
543
545{
546 bool ok = true;
547 for (auto iter = ismap_.begin(); iter != ismap_.end();)
548 {
549 if (iter->second->size() <= 0)
550 {
551 etiss::log(etiss::WARNING, "Removed empty etiss::instr::InstructionSet during compilation.", *iter->second);
552 ismap_.erase(iter++);
553 }
554 else
555 {
556 ok = ok & iter->second->compile();
557 iter++;
558 }
559 }
560 if (ismap_.begin() != ismap_.end())
561 width_ = ismap_.begin()->first;
562 return ok;
563}
564
566{
567 auto f = ismap_.find(width);
568 if (f != ismap_.end())
569 return f->second;
570 return nullptr;
571}
572InstructionSet *VariableInstructionSet::create(unsigned width, const std::string &name)
573{
574 auto f = ismap_.find(width);
575 if (f != ismap_.end())
576 return nullptr;
577 InstructionSet *ret = new InstructionSet(*this, width, name);
578 ismap_[width] = ret;
579 return ret;
580}
581InstructionSet &VariableInstructionSet::open(unsigned width, const std::string &name)
582{
583 InstructionSet *ret = get(width);
584 if (ret != nullptr)
585 {
586 return *ret;
587 }
588 return *create(width, name);
589}
590
591void VariableInstructionSet::foreach (std::function<void(InstructionSet &)> call)
592{
593 for (auto iter = ismap_.begin(); iter != ismap_.end(); iter++)
594 {
595 if (iter->second != nullptr)
596 {
597 call(*(iter->second));
598 }
599 else
600 {
601 etiss_log(ERROR, "invalid pointer in ismap_.");
602 }
603 }
604}
605
606std::string VariableInstructionSet::print(std::string prefix)
607{
608 std::stringstream ss;
609 ss << prefix << archname_ << "[default: " << width_ << "]:\n";
610 foreach ([&ss, &prefix](InstructionSet &is) { ss << is.print(prefix + "\t"); })
611 ;
612 return ss.str();
613}
614
615ModedInstructionSet::ModedInstructionSet(const std::string &name) : archname_(name) {}
617{
618 // delete variable instruction sets
619 for (auto iter = vismap_.begin(); iter != vismap_.end(); ++iter)
620 {
621 delete iter->second;
622 }
623}
625{
626 auto f = vismap_.find(mode);
627 if (f != vismap_.end())
628 return f->second;
629 return nullptr;
630}
631VariableInstructionSet *ModedInstructionSet::create(uint32_t mode, unsigned width, const std::string &name)
632{
633 auto f = vismap_.find(mode);
634 if (f != vismap_.end())
635 {
636#if DEBUG
637 if (f->second->width_ != width)
638 {
639 etiss_log(ERROR, "missmatch width values");
640 }
641#endif
642 return nullptr;
643 }
644 VariableInstructionSet *ret = new VariableInstructionSet(*this, width, name);
645 vismap_[mode] = ret;
646 invvismap_[ret] = mode;
647 return ret;
648}
649VariableInstructionSet &ModedInstructionSet::open(uint32_t mode, unsigned width, const std::string &name)
650{
651 VariableInstructionSet *ret = get(mode);
652 if (ret != nullptr)
653 {
654#if DEBUG
655 if (ret->width_ != width)
656 {
657 etiss_log(ERROR, "missmatch width values");
658 }
659#endif
660 return *ret;
661 }
662 return *create(mode, width, name);
663}
665{
666 auto iter = invvismap_.find(vis);
667 if (iter != invvismap_.end())
668 return iter->second;
670 "variable instruction set mode cannot be found since this moded instruction set is not its parent");
671 return (uint32_t)-1;
672}
673
674void ModedInstructionSet::foreach (std::function<void(VariableInstructionSet &)> call)
675{
676 for (auto iter = vismap_.begin(); iter != vismap_.end(); iter++)
677 {
678 if (iter->second != nullptr)
679 {
680 call(*(iter->second));
681 }
682 else
683 {
684 etiss_log(ERROR, "invalid pointer in vismap_.");
685 }
686 }
687}
688
690{
691 bool ok = true;
692 foreach ([&ok](VariableInstructionSet &vis) { ok = ok & vis.compile(); })
693 ;
694 return ok;
695}
696
697std::string ModedInstructionSet::print(std::string prefix)
698{
699 std::stringstream ss;
700 ss << prefix << archname_ << ":\n";
701 foreach ([&ss, &prefix](VariableInstructionSet &vis) {
702 ss << prefix << "MODE " << vis.parent_.getMode(vis) << ": ";
703 ss << vis.print(prefix + "\t");
704 })
705 ;
706 return ss.str();
707}
708
710{
711 foreach ([&set, &ok](InstructionClass &klass) {
712 VariableInstructionSet &vis = set.open(klass.mode_, klass.width_, klass.name_);
713 klass.addTo(vis, ok);
714 })
715 ;
716}
718{
719 foreach ([&set, &ok](InstructionGroup &group) {
720 InstructionSet &is = set.open(group.width_, group.name_);
721 group.addTo(is, ok);
722 })
723 ;
724}
726{
727 foreach ([&set, &ok](InstructionDefinition &id) {
728 Instruction *instr = set.create(id.opc_, id.name_);
729 if (instr == nullptr)
730 {
731 ok = false;
732 etiss::log(ERROR, "failed to add InstructionDefinition to Instruction set.", id, set);
733 return;
734 }
735 id.addTo(*instr, ok);
736 })
737 ;
738}
740{
741
742 if (!(opc_ == instr.opc_))
743 {
744 etiss::log(etiss::ERROR, "cannot add instruction definition to instruction.", *this, instr);
745 ok = false;
746 return;
747 }
748 etiss::log(VERBOSE, "Added instruction definition to instruction.", *this, instr);
750 if (ASMprinter_)
751 {
753 }
754}
755
756#if __cplusplus >= 201103L
757uint32_t operator"" _i32(const char *s)
758{
759 return parse_i32(s);
760}
761#endif
762uint32_t parse_i32(const char *s)
763{
764 return parse_i<uint32_t>(s);
765}
766
767} // namespace instr
768
769} // namespace etiss
contains container classes to store instruction definitions + translation functions and build a trans...
#define ETISS_SRCLOC
Definition Misc.h:239
#define etiss_log(LEVEL, MSG)
Definition Misc.h:83
__device__ __2f16 b
__device__ __2f16 float bool s
static __inline__ uint32_t
Definition arm_cde.h:25
static __inline__ int8_t
Definition arm_mve.h:311
A set of CodeParts.
Definition CodePart.h:437
BitArray::size_type end()
lowest bit of the range (included).
BitArray::size_type start()
highest bit of the range (included)
etiss_del_como(BitArrayRange) private BitArray::size_type endpos
void write(BitArray &ba, I val)
write the bit from the passed value starting at the lsb to the range.
I read(const BitArray &ba)
reads bits from the range to the return value starting at the lsb.
BitArrayRange(unsigned endindex_included, unsigned startindex_included)
stores a bit vector
static std::vector< BitArray > permutate(const BitArray &input, std::vector< size_type > indexes)
permutates the given input at the specified indexes.
void set_value(size_type width, unsigned long value)
change the value the object is holding
BitArray get_range(size_type end, size_type start) const
get the interval [end, start]
unsigned byteCount() const
std::string to_string() const
string representation of the BitArray
unsigned intCount() const
void set_range(unsigned long val, size_type end, size_type start)
set the value to the interval [end, start]
unsigned internalBufferSize()
char * internalBuffer()
get the internal buffer
void recoverFromEndianness(unsigned alignment, endian_t endianness)
changes byte positions as needed to resove endiannes incompabilities after using the internal buffer ...
maps to VariableInstructionSet
void addTo(VariableInstructionSet &set, bool &ok)
void addTo(ModedInstructionSet &set, bool &ok)
this class contains parameters that persist in between instruction lookpus/translation within a trans...
std::map< std::string, unsigned > ufields_
additional fields that can be used by any plugin/architecture.
unsigned & ufield(std::string name)
void addTo(Instruction &set, bool &ok)
const std::function< bool(BitArray &, etiss::CodeSet &, InstructionContext &)> callback_
const std::function< std::string(BitArray &, Instruction &)> ASMprinter_
maps to InstructionSet
void addTo(InstructionSet &set, bool &ok)
holds etiss::instr::Instruction instances and handles automatic instruction tree creation.
std::map< const OPCode *, Instruction *, etiss::instr::less > instrmap_
Instruction * get(const OPCode &key)
std::string print(std::string prefix, bool printunused=false)
Instruction * resolve(BitArray &instr)
void foreach(std::function< void(Instruction &)> func)
Instruction * create(const OPCode &key, const std::string &name)
Instruction & open(const OPCode &key, const std::string &name)
InstructionSet(VariableInstructionSet &parent, unsigned width, const std::string &name, unsigned c_size=4)
holds information and translation callbacks for an instruction.
bool addCallback(std::function< bool(BitArray &, etiss::CodeSet &, InstructionContext &)> callback, uint32_t builtinGroups, const std::set< uint32_t > &groups=std::set< uint32_t >())
std::set< uint32_t > & presentGroups()
bool translate(BitArray &, CodeSet &cs, InstructionContext &context)
uint32_t & presentBuiltinGroups()
void setASMPrinter(std::function< std::string(BitArray &, Instruction &)> printer)
const std::string name_
std::function< std::string(BitArray &, Instruction &)> printer_
static std::string printASMSimple(BitArray &ba, Instruction &instr)
Instruction(const OPCode &opc, const std::string &name)
virtual std::string print(std::string indent, I pos, unsigned pfillwidth, bool printunused=false)
std::string printASM(BitArray &)
std::set< uint32_t > groups_
std::list< std::tuple< std::function< bool(BitArray &, etiss::CodeSet &, InstructionContext &)>, uint32_t, std::set< uint32_t > > > callbacks_
holds etiss::instr::VariableInstructionSet instances for different modes.
std::string print(std::string prefix=std::string())
etiss_del_como(ModedInstructionSet) ModedInstructionSet(const std ~ModedInstructionSet()
VariableInstructionSet * create(uint32_t mode, unsigned width, const std::string &name=std::string())
std::map< VariableInstructionSet *, uint32_t > invvismap_
VariableInstructionSet & open(uint32_t mode, unsigned width, const std::string &name=std::string())
uint32_t getMode(VariableInstructionSet *vis)
VariableInstructionSet * get(uint32_t mode)
std::map< uint32_t, VariableInstructionSet * > vismap_
void foreach(std::function< void(VariableInstructionSet &)> call)
defines the relevant bits and their value to identify an instruction.
OPCode(unsigned width, const T code, const T mask)
ctor that uses integral values for mask and code
const BitArray code_
bool operator<(const OPCode &o) const
comparison operator for map/sets.
const BitArray mask_
holds etiss::instr::InstructionSet instances with different bit widths.
void foreach(std::function< void(InstructionSet &)> func)
InstructionSet & open(unsigned width, const std::string &name=std::string())
std::string print(std::string prefix=std::string())
InstructionSet * get(unsigned width)
std::map< unsigned, InstructionSet * > ismap_
InstructionSet * create(unsigned width, const std::string &name=std::string())
std::set< Instruction * > Node
Holding unique instruction sets code chunks after permutation.
BitArray::size_type size_type
uint32_t I
Definition Instruction.h:80
uint32_t parse_i32(const char *s)
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition Benchmark.h:53
endian_t
Enumeration type for the endianness.
Definition Misc.h:525
@ VERBOSE
Definition Misc.h:130
@ WARNING
Definition Misc.h:128
@ ERROR
Definition Misc.h:127
@ FATALERROR
Definition Misc.h:126
endian_t getEndianness()
evaluates the endianness of the current build as a constexpr.
Definition Misc.h:542
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:125
bool operator()(const OPCode *const &o1, const OPCode *const &o2) const