ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
RV64IMACFDArchSpecificImp.cpp
Go to the documentation of this file.
1
11#include <vector>
12
13#include "RV64IMACFDArch.h"
15#include "RV64IMACFDFuncs.h"
16#include "etiss/Memory.h"
17
34etiss::int32 RV64IMACFDArch::handleException(etiss::int32 cause, ETISS_CPU *cpu)
35{
36 RV64IMACFD_translate_exc_code(cpu, nullptr, nullptr, cause);
37 cpu->instructionPointer = cpu->nextPc;
38 return 0;
39}
40
45{
46 static etiss::ModuleHandle hModule = 0;
47
48 if (!hModule)
49 {
51 }
52
53 return hModule;
54}
55
59static std::string GetCurrentModulePath()
60{
61 static std::string modulePath;
62
63 if (modulePath == "")
64 {
66 }
67
68 return modulePath;
69}
70
74std::string RV64IMACFDArch::installDir() const
75{
76 auto archLib = GetCurrentModulePath();
77 auto libPathLoc = archLib.find_last_of("/\\");
78 auto libPath = archLib.substr(0, libPathLoc);
79 auto pluginsPathLoc = libPath.find_last_of("/\\");
80 auto pluginsPath = libPath.substr(0, pluginsPathLoc);
81 auto archPathLoc = pluginsPath.find_last_of("/\\");
82 return libPath.substr(0, archPathLoc);
83}
84
88std::string RV64IMACFDArch::jitFiles() const
89{
90 return installDir() + "/include/jit";
91}
92
118{
119 {
120 std::string requiredJitFilesPath = jitFiles();
121 /* Set default JIT Extensions. Read Parameters set from ETISS configuration and append with architecturally needed */
122 std::string cfgPar = "";
123 cfgPar = etiss::cfg().get<std::string>("jit.external_headers", ";");
124 etiss::cfg().set<std::string>("jit.external_headers", cfgPar + "etiss/jit/libsoftfloat.h");
125
126 cfgPar = etiss::cfg().get<std::string>("jit.external_libs", ";");
127 etiss::cfg().set<std::string>("jit.external_libs", cfgPar + "softfloat");
128
129 cfgPar = etiss::cfg().get<std::string>("jit.external_header_paths", ";");
130 etiss::cfg().set<std::string>("jit.external_header_paths", cfgPar + "etiss/jit" + requiredJitFilesPath);
131
132 cfgPar = etiss::cfg().get<std::string>("jit.external_lib_paths", ";");
133 etiss::cfg().set<std::string>("jit.external_lib_paths", cfgPar + "etiss/jit");
134 }
135
136 if (false) {
137 // Pre-compilation of instruction set to view instruction tree. Enable by setting 'true' above.
138
139 etiss::instr::ModedInstructionSet iset("RV64IMACFDISA");
140 bool ok = true;
141 RV64IMACFDISA.addTo(iset, ok);
142
143 iset.compile();
144
145 std::cout << iset.print() << std::endl;
146 }
147
148 bool ok = true;
149 RV64IMACFDISA.addTo(mis, ok);
150 if (!ok)
151 etiss::log(etiss::FATALERROR, "Failed to add instructions for RV64IMACFDISA");
152
154
155 using namespace etiss;
156 using namespace etiss::instr;
157
158 vis->get(32)->getInvalid().addCallback(
159 [] (BitArray & ba,etiss::CodeSet & cs,InstructionContext & ic)
160 {
161
162// -----------------------------------------------------------------------------
163
164// -----------------------------------------------------------------------------
165
166// -----------------------------------------------------------------------------
167// NOLINTBEGIN(clang-diagnostic-unused-but-set-variable)
168etiss_uint32 error_code = 0;
169static BitArrayRange R_error_code_0(31, 0);
170error_code += R_error_code_0.read(ba) << 0;
171
172// NOLINTEND(clang-diagnostic-unused-but-set-variable)
173// -----------------------------------------------------------------------------
174
175 {
176 CodePart & cp = cs.append(CodePart::INITIALREQUIRED);
177
178 cp.code() = std::string("//trap_entry 32\n");
179
180// -----------------------------------------------------------------------------
181{ // procedure
182cp.code() += "{ // procedure\n";
183cp.code() += "RV64IMACFD_translate_exc_code(cpu, system, plugin_pointers, " + std::to_string(error_code) + "ULL);\n";
184cp.code() += "goto instr_exit_" + std::to_string(ic.current_address_) + ";\n";
185cp.code() += "} // procedure\n";
186} // procedure
187cp.code() += "instr_exit_" + std::to_string(ic.current_address_) + ":\n";
188cp.code() += "cpu->instructionPointer = cpu->nextPc;\n";
189// -----------------------------------------------------------------------------
190 cp.getAffectedRegisters().add("instructionPointer", 32);
191 }
192 {
193 CodePart & cp = cs.append(CodePart::APPENDEDRETURNINGREQUIRED);
194
195 cp.code() = std::string("//trap_entry 32\n");
196
197// -----------------------------------------------------------------------------
198cp.code() += "return cpu->exception;\n";
199// -----------------------------------------------------------------------------
200 }
201
202 return true;
203 },
204 0
205 );
206
207 vis->get(16)->getInvalid().addCallback(
208 [] (BitArray & ba,etiss::CodeSet & cs,InstructionContext & ic)
209 {
210
211// -----------------------------------------------------------------------------
212
213// -----------------------------------------------------------------------------
214
215// -----------------------------------------------------------------------------
216// NOLINTBEGIN(clang-diagnostic-unused-but-set-variable)
217etiss_uint32 error_code = 0;
218static BitArrayRange R_error_code_0(31, 0);
219error_code += R_error_code_0.read(ba) << 0;
220
221// NOLINTEND(clang-diagnostic-unused-but-set-variable)
222// -----------------------------------------------------------------------------
223
224 {
225 CodePart & cp = cs.append(CodePart::INITIALREQUIRED);
226
227 cp.code() = std::string("//trap_entry 16\n");
228
229// -----------------------------------------------------------------------------
230{ // procedure
231cp.code() += "{ // procedure\n";
232cp.code() += "RV64IMACFD_translate_exc_code(cpu, system, plugin_pointers, " + std::to_string(error_code) + "ULL);\n";
233cp.code() += "goto instr_exit_" + std::to_string(ic.current_address_) + ";\n";
234cp.code() += "} // procedure\n";
235} // procedure
236cp.code() += "instr_exit_" + std::to_string(ic.current_address_) + ":\n";
237cp.code() += "cpu->instructionPointer = cpu->nextPc;\n";
238// -----------------------------------------------------------------------------
239 cp.getAffectedRegisters().add("instructionPointer", 32);
240 }
241 {
242 CodePart & cp = cs.append(CodePart::APPENDEDRETURNINGREQUIRED);
243
244 cp.code() = std::string("//trap_entry 16\n");
245
246// -----------------------------------------------------------------------------
247cp.code() += "return cpu->exception;\n";
248// -----------------------------------------------------------------------------
249 }
250
251 return true;
252 },
253 0
254 );
255
256
258 std::function<void(InstructionContext & ic, etiss_uint32 opRd)> updateRV64IMACFDInstrLength =
259 [](InstructionContext &ic, etiss_uint32 opRd) {
261 ic.is_not_default_width_ = true;
262 if (opRd == 0x3f)
263 ic.instr_width_ = 64;
264 else if ((opRd & 0x3f) == 0x1f)
265 ic.instr_width_ = 48;
266 else if (((opRd & 0x1f) >= 0x3) && ((opRd & 0x1f) < 0x1f))
267 ic.instr_width_ = 32;
268 else if(opRd == 0x7f) /* P-Extension instructions */
269 ic.instr_width_ = 32;
270 else if ((opRd & 0x3) != 0x3)
271 ic.instr_width_ = 16;
272 else
273 // This might happen when code is followed by data.
274 ic.is_not_default_width_ = false;
275 };
276
277 BitArrayRange op(6, 0);
278 etiss_uint32 opRd = op.read(ba);
279
280 /*BitArrayRange fullOp(ba.byteCount()*8-1,0);
281 etiss_uint32 fullOpRd = fullOp.read(ba);
282
283 std::stringstream ss;
284 ss << "Byte count: " << ba.byteCount()<< std::endl;
285 ss << "opcode: 0x" <<std::hex<< fullOpRd << std::endl;
286 ss << "Current PC: 0x" <<std::hex<< ic.current_address_ << std::endl;
287 std::cout << ss.str() << std::endl;*/
288
289 switch (ba.byteCount())
290 {
291 case 2:
292 if (((opRd & 0x3) != 0x3) || (opRd == 0))
293 {
294 ic.is_not_default_width_ = false;
295 break;
296 }
297 else
298 {
299 updateRV64IMACFDInstrLength(ic, opRd);
300 break;
301 }
302 case 4:
303 if ((((opRd & 0x1f) >= 0x3) || ((opRd & 0x1f) < 0x1f)) || (opRd == 0))
304 {
305 ic.is_not_default_width_ = false;
306 break;
307 }
308 else if(opRd == 0x7f) /* P-Extension instructions */
309 {
310 updateRV64IMACFDInstrLength(ic, opRd);
311 break;
312 }
313 else
314 {
315 updateRV64IMACFDInstrLength(ic, opRd);
316 break;
317 }
318 case 6:
319 if (((opRd & 0x3f) == 0x1f) || (opRd == 0))
320 {
321 ic.is_not_default_width_ = false;
322 break;
323 }
324 else
325 {
326 updateRV64IMACFDInstrLength(ic, opRd);
327 break;
328 }
329 case 8:
330 if ((opRd == 0x3f) || (opRd == 0))
331 {
332 ic.is_not_default_width_ = false;
333 break;
334 }
335 else
336 {
337 updateRV64IMACFDInstrLength(ic, opRd);
338 break;
339 }
340 default:
341 // This might happen when code is followed by data.
342 ic.is_not_default_width_ = false;
343 }
344 };
345
346}
347
372{
373 /**************************************************************************
374 * Endianess compensation *
375 **************************************************************************/
376}
377
378std::shared_ptr<etiss::VirtualStruct> RV64IMACFDArch::getVirtualStruct(ETISS_CPU *cpu)
379{
380 auto ret = etiss::VirtualStruct::allocate(cpu, [](etiss::VirtualStruct::Field *f) { delete f; });
381
382 for (uint32_t i = 0; i < 32; i += 1)
383 {
384 ret->addField(new RegField_RV64IMACFD(*ret, i));
385 }
386 for (uint32_t i = 0; i < 32; i += 1)
387 {
388 ret->addField(new FloatRegField_RV64IMACFD(*ret, i));
389 }
390 for (uint32_t i = 1; i < 4; i += 1)
391 {
392 ret->addField(new CSRField_RV64IMACFD(*ret, i));
393 }
394 for (uint32_t i = 768; i < 775; i += 1)
395 {
396 ret->addField(new CSRField_RV64IMACFD(*ret, i));
397 }
398 for (uint32_t i = 832; i < 837; i += 1)
399 {
400 ret->addField(new CSRField_RV64IMACFD(*ret, i));
401 }
402 ret->addField(new CSRField_RV64IMACFD(*ret, 2816));
403 ret->addField(new CSRField_RV64IMACFD(*ret, 2818));
404 ret->addField(new CSRField_RV64IMACFD(*ret, 2944));
405 ret->addField(new CSRField_RV64IMACFD(*ret, 2946));
406 for (uint32_t i = 3072; i < 3075; i += 1)
407 {
408 ret->addField(new CSRField_RV64IMACFD(*ret, i));
409 }
410 for (uint32_t i = 3200; i < 3203; i += 1)
411 {
412 ret->addField(new CSRField_RV64IMACFD(*ret, i));
413 }
414 for (uint32_t i = 3857; i < 3861; i += 1)
415 {
416 ret->addField(new CSRField_RV64IMACFD(*ret, i));
417 }
418 ret->addField(new pcField_RV64IMACFD(*ret));
419
420 return ret;
421}
422
431{
432 if (cpu == 0)
433 return 0;
434
435 std::vector<etiss::uint64 *> vec;
436 std::vector<etiss::uint64 *> mask;
437
438 vec.push_back(&((RV64IMACFD *)cpu)->MIP);
439 mask.push_back(&((RV64IMACFD *)cpu)->MIE);
440
442}
443
448
453
static std::string GetCurrentModulePath()
See etiss/src/Misc.cpp.
static etiss::ModuleHandle GetCurrentModule()
See etiss/src/Misc.cpp.
static std::string GetCurrentModulePath()
See etiss/src/Misc.cpp.
etiss::instr::InstructionCollection RV64IMACFDISA
void RV64IMACFD_translate_exc_code(ETISS_CPU *const cpu, ETISS_System *const system, void *const *const plugin_pointers, etiss_int32 cause)
static __inline__ uint32_t
Definition arm_cde.h:25
uint32_t etiss_uint32
Definition types.h:55
virtual void compensateEndianess(ETISS_CPU *cpu, etiss::instr::BitArray &ba) const
Target architecture may have inconsistent endianess.
virtual std::string installDir() const
This function will return the base installation directory of the ArchLib.
virtual etiss::int32 handleException(etiss::int32 code, ETISS_CPU *cpu)
This function will be called automatically in order to handling architecure dependent exceptions such...
virtual void initInstrSet(etiss::instr::ModedInstructionSet &) const
This function is called during CPUArch initialization.
virtual etiss::InterruptVector * createInterruptVector(ETISS_CPU *cpu)
If interrupt handling is expected, vector table could be provided to support interrupt triggering.
virtual void deleteInterruptEnable(etiss::InterruptEnable *en, ETISS_CPU *cpu)
virtual void deleteInterruptVector(etiss::InterruptVector *vec, ETISS_CPU *cpu)
delete an allocated interrupt vector object
virtual std::shared_ptr< etiss::VirtualStruct > getVirtualStruct(ETISS_CPU *cpu)
get the VirtualStruct of the core to mitigate register access
virtual etiss::InterruptEnable * createInterruptEnable(ETISS_CPU *cpu)
virtual std::string jitFiles() const
This function will return the include prefix relative to the base installation directory of the ArchL...
Generated on Fri, 19 Jun 2026 11:47:54 +0000.
Contains a small code snipped.
Definition CodePart.h:348
std::string & code()
Definition CodePart.h:378
RegisterSet & getAffectedRegisters()
Definition CodePart.h:376
A set of CodeParts.
Definition CodePart.h:399
void append(const CodePart &part, CodePart::TYPE type)
Definition CodePart.h:412
bool set(const std::string &key, T value)
template function to set the value of a configuration key.
Definition Misc.h:335
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:312
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:184
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.
I read(const BitArray &ba)
reads bits from the range to the return value starting at the lsb.
stores a bit vector
unsigned byteCount() const
void addTo(ModedInstructionSet &set, bool &ok)
this class contains parameters that persist in between instruction lookpus/translation within a trans...
bool is_not_default_width_
if true the this instruction is not as long as the width of the variable instruction set
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 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.
std::string print(std::string prefix=std::string())
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_
forwards: include/jit/*
Definition Benchmark.h:17
void * ModuleHandle
Represents a module handle. Analogous to Windows this represents the module base address,...
Definition Memory.h:37
etiss::ModuleHandle GetModuleByAddress(uintptr_t adr)
Definition Memory.cpp:90
std::string GetModulePath(etiss::ModuleHandle hModule)
Definition Memory.cpp:97
@ FATALERROR
Definition Misc.h:84
Configuration & cfg()
Definition Misc.cpp:548
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:94
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
basic cpu state structure needed for execution of any cpu architecture.
Definition CPU.h:51
etiss_uint64 instructionPointer
pointer to next instruction.
Definition CPU.h:54
etiss_uint64 nextPc
Definition CPU.h:57
Generated on Fri, 19 Jun 2026 11:47:54 +0000.
Definition RV64IMACFD.h:17