ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
CodePart.cpp
Go to the documentation of this file.
1 
53 #include "etiss/CodePart.h"
54 
55 using namespace etiss;
56 
57 void CodeSet::writeCodeParts(std::string &code, const std::list<CodePart> &parts, bool required, RegisterSet &ignored,
58  bool intersect)
59 {
60 
61  std::list<CodePart>::const_iterator iter = parts.begin();
62  while (iter != parts.end())
63  {
64  if (required)
65  { // no optional code; skip
66 
67  if (iter->fullRegistersDependency())
68  {
69  ignored.clear();
70  }
71  else
72  {
73  if (intersect)
74  {
75  ignored.intersect(iter->getAffectedRegisters());
76  }
77  else
78  {
79  ignored.merge(iter->getAffectedRegisters());
80  }
81  ignored.applyShadow(iter->getRegisterDependencies());
82  }
83  code = iter->getCode() + "\n" + code;
84  // std::cout << "used code: {"<< std::endl << iter->getCode() << std::endl << "}"<<std::endl;
85  }
86  else
87  {
88  if (!iter->getAffectedRegisters().maskedBy(ignored))
89  { // check if affected registers will be overwritten anyway
90 
91  if (iter->fullRegistersDependency())
92  { // requires all registers to be valid
93  ignored.clear();
94  }
95  else
96  {
97  if (intersect)
98  { // in case of return statements only intersection produces an alwasy valid state
99  ignored.intersect(iter->getAffectedRegisters());
100  }
101  else
102  {
103  ignored.merge(iter->getAffectedRegisters());
104  }
105  ignored.applyShadow(iter->getRegisterDependencies());
106  }
107 
108  code = iter->getCode() + "\n" + code;
109  // std::cout << "used code: {"<< std::endl << iter->getCode() << std::endl << "}"<<std::endl;
110  }
111  else
112  {
113  // std::cout << "removed code: {"<< std::endl << iter->getCode() << std::endl << "}"<<std::endl;
114  }
115  }
116  iter++;
117  }
118 }
119 
120 std::string CodeSet::toString(RegisterSet &ignored, bool &ok) const
121 {
122  ok = true;
123  std::string code;
124 
125  writeCodeParts(code, appretreq_parts_, true, ignored,
126  true); // std::cout << "Ignored 1: " << ignored._dbg_print() << std::endl;
127 
128  writeCodeParts(code, appopt_parts_, false, ignored,
129  false); // std::cout << "Ignored 2: " << ignored._dbg_print() << std::endl;
130 
131  writeCodeParts(code, appreq_parts_, true, ignored,
132  false); // std::cout << "Ignored 3: " << ignored._dbg_print() << std::endl;
133 
134  writeCodeParts(code, midopt_parts_, false, ignored,
135  false); // std::cout << "Ignored 4: " << ignored._dbg_print() << std::endl;
136 
137  writeCodeParts(code, inireq_parts_, true, ignored,
138  false); // std::cout << "Ignored 5: " << ignored._dbg_print() << std::endl;
139 
140  writeCodeParts(code, pindbgretreq_parts_, true, ignored,
141  true); // std::cout << "Ignored 6: " << ignored._dbg_print() << std::endl;
142 
143  return code;
144 }
145 
146 void CodeBlock::toCode(std::stringstream &out, const std::string &funcname, std::set<std::string> *fileglobalcode)
147 {
148 
149  if (fileglobalcode)
150  {
151  for (auto iter = fileglobal_code.begin(); iter != fileglobal_code.end(); iter++)
152  {
153  if (fileglobalcode->find(*iter) == fileglobalcode->end())
154  {
155  out << *iter;
156  fileglobalcode->insert(*iter);
157  }
158  }
159  }
160  else
161  {
162  for (auto iter = fileglobal_code.begin(); iter != fileglobal_code.end(); iter++)
163  {
164  out << *iter;
165  }
166  }
167 
168  out << "etiss_uint32 " << funcname
169  << "(ETISS_CPU * const cpu, ETISS_System * const system, void * const * const plugin_pointers) {\n"
170  " const etiss_uint64 blockglobal_startaddr = 0x"
171  << std::hex << startindex_ << std::dec
172  << "ULL;\n"
173  " const etiss_uint64 blockglobal_jumpaddr = cpu->instructionPointer - blockglobal_startaddr;\n";
174 
175  for (auto iter = functionglobal_code.begin(); iter != functionglobal_code.end(); iter++)
176  {
177  out << *iter;
178  }
179 
180  out << "\n\tswitch(blockglobal_jumpaddr){\n";
181  std::list<std::string> cases;
182  {
183  // write cases
184  RegisterSet ignored;
185 #if DEBUG
186  etiss::uint64 last = 0;
187 #endif
188  for (auto iter = lines_.rbegin(); iter != lines_.rend(); iter++)
189  {
190 #if DEBUG
191  if (last > iter->getAddress())
192  {
193  etiss::log(etiss::FATALERROR, "error in code block: the line addresses are not in ascending order");
194  }
195 #endif
196  bool ok = true; // TODO use result
197  std::stringstream lss;
198  lss << " case " << (iter->getAddress() - startindex_) << ":\n";
199  lss << " {\n";
200  lss << iter->getCodeSet().toString(ignored, ok);
201  lss << " }\n";
202  cases.push_front(lss.str());
203  }
204  }
205  for (auto iter = cases.begin(); iter != cases.end(); iter++)
206  out << *iter;
207  out << "\n\t break;\n"
208  "\tdefault:\n"
209  "\t\treturn ETISS_RETURNCODE_ILLEGALJUMP;\n"
210  "\t}"
211  "\treturn ETISS_RETURNCODE_NOERROR;\n"
212  "}\n\n";
213 }
etiss_uint64 uint64
Definition: 386-GCC.h:82
classes to hold code and additional information used for optimization of instruction translations
void toCode(std::stringstream &out, const std::string &funcname, std::set< std::string > *fileglobalcode)
Definition: CodePart.cpp:146
std::set< std::string > functionglobal_code
Definition: CodePart.h:613
std::vector< Line > lines_
Definition: CodePart.h:609
etiss::uint64 startindex_
Definition: CodePart.h:610
std::set< std::string > fileglobal_code
Definition: CodePart.h:612
std::string toString(RegisterSet &ignored, bool &ok) const
writes the contained CodeParts as needed with respect to the given RegisterSet of bits that are not r...
Definition: CodePart.cpp:120
std::list< CodePart > appretreq_parts_
Definition: CodePart.h:550
std::list< CodePart > midopt_parts_
Definition: CodePart.h:547
std::list< CodePart > pindbgretreq_parts_
Definition: CodePart.h:545
std::list< CodePart > appreq_parts_
Definition: CodePart.h:548
std::list< CodePart > inireq_parts_
Definition: CodePart.h:546
static void writeCodeParts(std::string &code, const std::list< CodePart > &parts, bool required, RegisterSet &ignored, bool intersect)
Definition: CodePart.cpp:57
std::list< CodePart > appopt_parts_
Definition: CodePart.h:549
set of register parts.
Definition: CodePart.h:201
void applyShadow(const RegisterSet &rs)
any register bits set in the passed RegisterSet won't be set in this RegisterSet
Definition: CodePart.h:250
void merge(const RegisterSet &rs)
any register bits set in the passed RegisterSet will be set in this RegisterSet (plus previously set ...
Definition: CodePart.h:279
void intersect(const RegisterSet &rs)
only register bits set in this AND the passed RegisterSet remain set in this RegisterSet
Definition: CodePart.h:291
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition: Benchmark.h:53
@ FATALERROR
Definition: Misc.h:126
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition: Misc.cpp:125