ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
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 
61 namespace etiss
62 {
63 
64 namespace instr
65 {
66 
68 
70 {
71  return static_cast<char *>(static_cast<void *>(d_));
72 }
74 {
75  return intcount_ * sizeof(I);
76 }
77 
78 void 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),
99  ETISS_SRCLOC);
100  }
101  }
102  }
103  else
104  {
105  etiss::log(etiss::FATALERROR, "bit swap notimplemented for this case", alignment, endianness, sizeof(I),
106  ETISS_SRCLOC);
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),
128  ETISS_SRCLOC);
129  }
130 
131 #endif
132 }
133 
134 unsigned BitArray::byteCount() const {
135  unsigned mod = size() % (8);
136  unsigned ret = (size() - mod) / (8);
137  if (mod > 0) ret++;
138  return ret;
139 }
140 unsigned 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 
147 std::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 
163 void BitArray::set_value(size_type width, unsigned long value){
164  BitArray b(width, value);
165  *this = b;
166 }
167 
168 void 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 
181 void 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 
188 std::string BitArray::to_string() const
189 {
190  std::string s;
191  boost::to_string(*this, s);
192  return s;
193 }
194 
195 BitArrayRange::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 
212 {
213  return startpos;
214 }
215 
217 {
218  return endpos;
219 }
220 
221 OPCode::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 
236 OPCode::OPCode(const OPCode &cpy) : code_(cpy.code_), mask_(cpy.mask_) {}
237 
238 bool 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 
247 bool 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 
261 unsigned &InstructionContext::ufield(std::string name)
262 {
263  return ufields_[name];
264 }
265 
266 Instruction::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 
277 std::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 }
284 bool 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 
331 {
332  return builtinGroups_;
333 }
334 std::set<uint32_t> &Instruction::presentGroups()
335 {
336  return groups_;
337 }
338 
340 {
341  return printer_(ba, *this);
342 }
343 
344 void Instruction::setASMPrinter(std::function<std::string(BitArray &, Instruction &)> printer)
345 {
346  printer_ = printer;
347  if (!printer_)
349 }
350 
351 InstructionSet::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 }
382 Instruction &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 }
396 Instruction *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 
484 std::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 
499 {
500  return invalid;
501 }
502 
503 void 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 
527 VariableInstructionSet::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 }
572 InstructionSet *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 }
581 InstructionSet &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 
591 void 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 
606 std::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 
615 ModedInstructionSet::ModedInstructionSet(const std::string &name) : archname_(name) {}
616 ModedInstructionSet::~ModedInstructionSet()
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 }
631 VariableInstructionSet *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 }
649 VariableInstructionSet &ModedInstructionSet::open(uint32_t mode, unsigned width, const std::string &name)
650 {
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 
674 void 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 
697 std::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  {
752  instr.setASMPrinter(ASMprinter_);
753  }
754 }
755 
756 #if __cplusplus >= 201103L
757 uint32_t operator"" _i32(const char *s)
758 {
759  return parse_i32(s);
760 }
761 #endif
762 uint32_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
Definition: Instruction.h:210
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
Definition: Instruction.h:161
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()
Definition: Instruction.cpp:73
char * internalBuffer()
get the internal buffer
Definition: Instruction.cpp:69
void recoverFromEndianness(unsigned alignment, endian_t endianness)
changes byte positions as needed to resove endiannes incompabilities after using the internal buffer ...
Definition: Instruction.cpp:78
maps to VariableInstructionSet
Definition: Instruction.h:638
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...
Definition: Instruction.h:337
std::map< std::string, unsigned > ufields_
additional fields that can be used by any plugin/architecture.
Definition: Instruction.h:375
unsigned & ufield(std::string name)
void addTo(Instruction &set, bool &ok)
const std::function< bool(BitArray &, etiss::CodeSet &, InstructionContext &)> callback_
Definition: Instruction.h:713
const std::function< std::string(BitArray &, Instruction &)> ASMprinter_
Definition: Instruction.h:714
maps to InstructionSet
Definition: Instruction.h:677
void addTo(InstructionSet &set, bool &ok)
holds etiss::instr::Instruction instances and handles automatic instruction tree creation.
Definition: Instruction.h:442
std::map< const OPCode *, Instruction *, etiss::instr::less > instrmap_
Definition: Instruction.h:480
Instruction * get(const OPCode &key)
std::string print(std::string prefix, bool printunused=false)
Instruction * resolve(BitArray &instr)
const std::string name_
Definition: Instruction.h:447
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.
Definition: Instruction.h:393
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_
Definition: Instruction.h:410
std::function< std::string(BitArray &, Instruction &)> printer_
Definition: Instruction.h:399
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_
Definition: Instruction.h:398
std::list< std::tuple< std::function< bool(BitArray &, etiss::CodeSet &, InstructionContext &)>, uint32_t, std::set< uint32_t > > > callbacks_
Definition: Instruction.h:396
holds etiss::instr::VariableInstructionSet instances for different modes.
Definition: Instruction.h:562
std::string print(std::string prefix=std::string())
VariableInstructionSet * create(uint32_t mode, unsigned width, const std::string &name=std::string())
std::map< VariableInstructionSet *, uint32_t > invvismap_
Definition: Instruction.h:567
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_
Definition: Instruction.h:566
void foreach(std::function< void(VariableInstructionSet &)> call)
defines the relevant bits and their value to identify an instruction.
Definition: Instruction.h:272
OPCode(unsigned width, const T code, const T mask)
ctor that uses integral values for mask and code
Definition: Instruction.h:283
const BitArray code_
Definition: Instruction.h:274
bool operator<(const OPCode &o) const
comparison operator for map/sets.
const BitArray mask_
Definition: Instruction.h:275
holds etiss::instr::InstructionSet instances with different bit widths.
Definition: Instruction.h:500
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_
Definition: Instruction.h:502
InstructionSet * create(unsigned width, const std::string &name=std::string())
std::set< Instruction * > Node
Holding unique instruction sets code chunks after permutation.
Definition: Instruction.h:155
BitArray::size_type size_type
Definition: Instruction.cpp:67
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
dictionary results
Definition: get_metrics.py:209
bool operator()(const OPCode *const &o1, const OPCode *const &o2) const
#define pow(__x, __y)
Definition: tgmath.h:490