ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
RV32IMACFDArchSpecificImp.cpp
Go to the documentation of this file.
1 
11 #include <vector>
12 
13 #include "RV32IMACFDArch.h"
15 #include "RV32IMACFDFuncs.h"
16 
32 {
33  RV32IMACFD_translate_exc_code(cpu, nullptr, nullptr, cause);
34  cpu->instructionPointer = cpu->nextPc;
35  return 0;
36 }
37 
61 {
62 
63  {
64  /* Set default JIT Extensions. Read Parameters set from ETISS configuration and append with architecturally needed */
65  std::string cfgPar = "";
66  cfgPar = etiss::cfg().get<std::string>("jit.external_headers", ";");
67  etiss::cfg().set<std::string>("jit.external_headers", cfgPar + "etiss/jit/libsoftfloat.h");
68 
69  cfgPar = etiss::cfg().get<std::string>("jit.external_libs", ";");
70  etiss::cfg().set<std::string>("jit.external_libs", cfgPar + "softfloat");
71 
72  cfgPar = etiss::cfg().get<std::string>("jit.external_header_paths", ";");
73  etiss::cfg().set<std::string>("jit.external_header_paths", cfgPar + "/etiss/jit");
74 
75  cfgPar = etiss::cfg().get<std::string>("jit.external_lib_paths", ";");
76  etiss::cfg().set<std::string>("jit.external_lib_paths", cfgPar + "/etiss/jit");
77 
78  }
79 
80  if (false) {
81  // Pre-compilation of instruction set to view instruction tree. Could be disabled.
82  etiss::instr::ModedInstructionSet iset("RV32IMACFDISA");
83  bool ok = true;
84  RV32IMACFDISA.addTo(iset,ok);
85 
86  iset.compile();
87 
88  std::cout << iset.print() << std::endl;
89  }
90 
91  bool ok = true;
92  RV32IMACFDISA.addTo(mis,ok);
93  if (!ok)
94  etiss::log(etiss::FATALERROR,"Failed to add instructions for RV32IMACFDISA");
95 
97 
98  using namespace etiss;
99  using namespace etiss::instr;
100 
101  vis->get(32)->getInvalid().addCallback(
102  [] (BitArray & ba,etiss::CodeSet & cs,InstructionContext & ic)
103  {
104 
105 // -----------------------------------------------------------------------------
106 
107 // -----------------------------------------------------------------------------
108 
109 // -----------------------------------------------------------------------------
110 etiss_uint32 error_code = 0;
111 static BitArrayRange R_error_code_0(31, 0);
112 error_code += R_error_code_0.read(ba) << 0;
113 
114 // -----------------------------------------------------------------------------
115 
116  {
117  CodePart & cp = cs.append(CodePart::INITIALREQUIRED);
118 
119  cp.code() = std::string("//trap_entry 32\n");
120 
121 // -----------------------------------------------------------------------------
122 { // procedure
123 cp.code() += "{ // procedure\n";
124 cp.code() += "RV32IMACFD_translate_exc_code(cpu, system, plugin_pointers, " + std::to_string(error_code) + "ULL);\n";
125 cp.code() += "goto instr_exit_" + std::to_string(ic.current_address_) + ";\n";
126 cp.code() += "} // procedure\n";
127 } // procedure
128 cp.code() += "instr_exit_" + std::to_string(ic.current_address_) + ":\n";
129 cp.code() += "cpu->instructionPointer = cpu->nextPc;\n";
130 // -----------------------------------------------------------------------------
131  cp.getAffectedRegisters().add("instructionPointer", 32);
132  }
133  {
134  CodePart & cp = cs.append(CodePart::APPENDEDRETURNINGREQUIRED);
135 
136  cp.code() = std::string("//trap_entry 32\n");
137 
138 // -----------------------------------------------------------------------------
139 cp.code() += "return cpu->exception;\n";
140 // -----------------------------------------------------------------------------
141  }
142 
143  return true;
144  },
145  0
146  );
147 
148  vis->get(16)->getInvalid().addCallback(
149  [] (BitArray & ba,etiss::CodeSet & cs,InstructionContext & ic)
150  {
151 
152 // -----------------------------------------------------------------------------
153 
154 // -----------------------------------------------------------------------------
155 
156 // -----------------------------------------------------------------------------
157 etiss_uint32 error_code = 0;
158 static BitArrayRange R_error_code_0(31, 0);
159 error_code += R_error_code_0.read(ba) << 0;
160 
161 // -----------------------------------------------------------------------------
162 
163  {
164  CodePart & cp = cs.append(CodePart::INITIALREQUIRED);
165 
166  cp.code() = std::string("//trap_entry 16\n");
167 
168 // -----------------------------------------------------------------------------
169 { // procedure
170 cp.code() += "{ // procedure\n";
171 cp.code() += "RV32IMACFD_translate_exc_code(cpu, system, plugin_pointers, " + std::to_string(error_code) + "ULL);\n";
172 cp.code() += "goto instr_exit_" + std::to_string(ic.current_address_) + ";\n";
173 cp.code() += "} // procedure\n";
174 } // procedure
175 cp.code() += "instr_exit_" + std::to_string(ic.current_address_) + ":\n";
176 cp.code() += "cpu->instructionPointer = cpu->nextPc;\n";
177 // -----------------------------------------------------------------------------
178  cp.getAffectedRegisters().add("instructionPointer", 32);
179  }
180  {
181  CodePart & cp = cs.append(CodePart::APPENDEDRETURNINGREQUIRED);
182 
183  cp.code() = std::string("//trap_entry 16\n");
184 
185 // -----------------------------------------------------------------------------
186 cp.code() += "return cpu->exception;\n";
187 // -----------------------------------------------------------------------------
188  }
189 
190  return true;
191  },
192  0
193  );
194 
196  std::function<void(InstructionContext & ic, etiss_uint32 opRd)> updateRV32IMACFDInstrLength =
197  [](InstructionContext &ic, etiss_uint32 opRd) {
199  ic.is_not_default_width_ = true;
200  if (opRd == 0x3f)
201  ic.instr_width_ = 64;
202  else if ((opRd & 0x3f) == 0x1f)
203  ic.instr_width_ = 48;
204  else if (((opRd & 0x1f) >= 0x3) && ((opRd & 0x1f) < 0x1f))
205  ic.instr_width_ = 32;
206  else if(opRd == 0x7f) /* P-Extension instructions */
207  ic.instr_width_ = 32;
208  else if ((opRd & 0x3) != 0x3)
209  ic.instr_width_ = 16;
210  else
211  // This might happen when code is followed by data.
212  ic.is_not_default_width_ = false;
213  };
214 
215  BitArrayRange op(6, 0);
216  etiss_uint32 opRd = op.read(ba);
217 
218  /*BitArrayRange fullOp(ba.byteCount()*8-1,0);
219  etiss_uint32 fullOpRd = fullOp.read(ba);
220 
221  std::stringstream ss;
222  ss << "Byte count: " << ba.byteCount()<< std::endl;
223  ss << "opcode: 0x" <<std::hex<< fullOpRd << std::endl;
224  ss << "Current PC: 0x" <<std::hex<< ic.current_address_ << std::endl;
225  std::cout << ss.str() << std::endl;*/
226 
227  switch (ba.byteCount())
228  {
229  case 2:
230  if (((opRd & 0x3) != 0x3) || (opRd == 0))
231  {
232  ic.is_not_default_width_ = false;
233  break;
234  }
235  else
236  {
237  updateRV32IMACFDInstrLength(ic, opRd);
238  break;
239  }
240  case 4:
241  if ((((opRd & 0x1f) >= 0x3) || ((opRd & 0x1f) < 0x1f)) || (opRd == 0))
242  {
243  ic.is_not_default_width_ = false;
244  break;
245  }
246  else if(opRd == 0x7f) /* P-Extension instructions */
247  {
248  updateRV32IMACFDInstrLength(ic, opRd);
249  break;
250  }
251  else
252  {
253  updateRV32IMACFDInstrLength(ic, opRd);
254  break;
255  }
256  case 6:
257  if (((opRd & 0x3f) == 0x1f) || (opRd == 0))
258  {
259  ic.is_not_default_width_ = false;
260  break;
261  }
262  else
263  {
264  updateRV32IMACFDInstrLength(ic, opRd);
265  break;
266  }
267  case 8:
268  if ((opRd == 0x3f) || (opRd == 0))
269  {
270  ic.is_not_default_width_ = false;
271  break;
272  }
273  else
274  {
275  updateRV32IMACFDInstrLength(ic, opRd);
276  break;
277  }
278  default:
279  // This might happen when code is followed by data.
280  ic.is_not_default_width_ = false;
281  }
282  };
283 
284 }
285 
310 {
311  /**************************************************************************
312  * Endianess compensation *
313  ***************************************************************************/
314 }
315 
316 std::shared_ptr<etiss::VirtualStruct> RV32IMACFDArch::getVirtualStruct(ETISS_CPU * cpu)
317 {
319  cpu,
321  delete f;
322  }
323  );
324 
325  for (uint32_t i = 0; i < 32; ++i){
326  ret->addField(new RegField_RV32IMACFD(*ret,i));
327  }
328 
329  ret->addField(new pcField_RV32IMACFD(*ret));
330  return ret;
331 }
332 
341 {
342  if (cpu == 0)
343  return 0;
344 
345  std::vector<etiss::uint32 *> vec;
346  std::vector<etiss::uint32 *> mask;
347 
348  vec.push_back(&((RV32IMACFD*)cpu)->MIP);
349  mask.push_back(&((RV32IMACFD*)cpu)->MIE);
350 
351  return new etiss::MappedInterruptVector<etiss::uint32>(vec, mask);
352 }
353 
355 {
356  delete vec;
357 }
358 
360  return new etiss::MappedInterruptEnable<etiss::uint32>(&((RV32IMACFD*)cpu)->MSTATUS, 15);
361 }
362 
364  delete en;
365 }
etiss_int32 int32
Definition: 386-GCC.h:81
etiss::instr::InstructionCollection RV32IMACFDISA("RV32IMACFDISA", ISA16_RV32IMACFDClass, ISA32_RV32IMACFDClass)
void RV32IMACFD_translate_exc_code(ETISS_CPU *const cpu, ETISS_System *const system, void *const *const plugin_pointers, etiss_int32 cause)
if(__y==0) return __x
static __inline__ uint32_t
Definition: arm_cde.h:25
uint32_t etiss_uint32
Definition: types.h:93
virtual void deleteInterruptVector(etiss::InterruptVector *vec, ETISS_CPU *cpu)
delete an allocated interrupt vector object
virtual void deleteInterruptEnable(etiss::InterruptEnable *en, ETISS_CPU *cpu)
virtual void initInstrSet(etiss::instr::ModedInstructionSet &) const
This function is called during CPUArch initialization.
virtual etiss::InterruptEnable * createInterruptEnable(ETISS_CPU *cpu)
virtual etiss::InterruptVector * createInterruptVector(ETISS_CPU *cpu)
If interrupt handling is expected, vector table could be provided to support interrupt triggering.
virtual std::shared_ptr< etiss::VirtualStruct > getVirtualStruct(ETISS_CPU *cpu)
get the VirtualStruct of the core to mitigate register access
virtual void compensateEndianess(ETISS_CPU *cpu, etiss::instr::BitArray &ba) const
Target architecture may have inconsistent endianess.
virtual etiss::int32 handleException(etiss::int32 code, ETISS_CPU *cpu)
This function will be called automatically in order to handling architecure dependent exceptions such...
Generated on Wed, 08 May 2024 17:36:07 +0200.
Contains a small code snipped.
Definition: CodePart.h:386
std::string & code()
Definition: CodePart.h:416
RegisterSet & getAffectedRegisters()
Definition: CodePart.h:414
A set of CodeParts.
Definition: CodePart.h:437
void append(const CodePart &part, CodePart::TYPE type)
Definition: CodePart.h:450
bool set(const std::string &key, T value)
template function to set the value of a configuration key.
Definition: Misc.h:372
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
interface to set interrupt bits
template implementation of an InterruptVector that uses integer variables to store interrupt bit valu...
void add(const RegisterPart &rp)
add a registerPart to the set or just its relevant bits if a register with the same name is already p...
Definition: CodePart.h:222
a Field instance represents e.g.
static std::shared_ptr< VirtualStruct > allocate(void *structure, std::function< void(Field *)> delete_)
Reading through it will only return bits within the range.
Definition: Instruction.h:208
I read(const BitArray &ba)
reads bits from the range to the return value starting at the lsb.
stores a bit vector
Definition: Instruction.h:161
unsigned byteCount() const
void addTo(ModedInstructionSet &set, bool &ok)
this class contains parameters that persist in between instruction lookpus/translation within a trans...
Definition: Instruction.h:337
bool is_not_default_width_
if true the this instruction is not as long as the width of the variable instruction set
Definition: Instruction.h:346
bool instr_width_fully_evaluated_
if true the length_updater_ function will be called again after instr_width_ bits are available
Definition: Instruction.h:349
uint64_t current_address_
start address of current instruction
Definition: Instruction.h:366
bool addCallback(std::function< bool(BitArray &, etiss::CodeSet &, InstructionContext &)> callback, uint32_t builtinGroups, const std::set< uint32_t > &groups=std::set< uint32_t >())
holds etiss::instr::VariableInstructionSet instances for different modes.
Definition: Instruction.h:562
std::string print(std::string prefix=std::string())
VariableInstructionSet * get(uint32_t mode)
holds etiss::instr::InstructionSet instances with different bit widths.
Definition: Instruction.h:500
InstructionSet * get(unsigned width)
std::function< void(VariableInstructionSet &, InstructionContext &, BitArray &)> length_updater_
Definition: Instruction.h:508
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition: Benchmark.h:53
@ FATALERROR
Definition: Misc.h:126
Configuration & cfg(const std::string &cfgName)
Get reference of the global ETISS configuration object.
Definition: Misc.cpp:560
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition: Misc.cpp:125
basic cpu state structure needed for execution of any cpu architecture.
Definition: CPU.h:89
etiss_uint64 instructionPointer
pointer to next instruction.
Definition: CPU.h:92
etiss_uint64 nextPc
Definition: CPU.h:95
Generated on Wed, 08 May 2024 17:36:07 +0200.
Definition: RV32IMACFD.h:16