Jet*_*ura 4 c++ qemu mips emulation riscv
我尝试实现功能ISA模拟器:目标是RISC-V和MIPS.这是一步一步的指令翻译.
抽象步骤:
while(num_steps)
{
try
{
take_interrupt();// take pending interrupts
fetch(); // fetch instruction from memory
decode(); // find handler to instruction
execute(); // perform instruction
}
catch (Trap& e)
{
take_trap(e); //configure appropriate system registers and jump to trap vector.
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,C++异常用于传输控制流.也许有更帅气的设计?
问题:在功能性ISA模拟器上实现陷阱的最佳方法/实践是什么.我也对翻译模拟器的异常/陷阱实现感兴趣,比如QEMU.
注意:通过单词trap我的意思是ISA定义的陷阱,而不是应用程序错误:未对齐的内存访问,非法指令,系统寄存器访问错误,权限级别更改等.
QEMU使用C setjmp()/ longjmp()机制来处理大多数异常:当我们检测到类似页面错误的东西时,我们设置一些标志来指示异常的类型,然后将longjmp()放到顶层"执行"代码"循环.然后该循环查看标志并在继续执行访客代码之前为"输入异常处理程序"设置CPU状态.
所以我们使用相当于抛出异常的C; 正如NonNumeric所说,没有要求像这样实现客户端异常(名称巧合只是巧合).但由于触发页面错误的内存访问是非常见的情况,因此longjmp或抛出C++异常更有效,而不是在所有内存访问代码路径中包含"handle failure return".访客内存访问是一个特定的热点,QEMU通过一些自定义内联汇编实现其内存访问快速路径,因此我们关心在没有执行longjmp的情况下退出到页面错误的顶级循环所需的额外少数指令.使用简单的"获取/解码/执行"循环而不执行客户代码JIT的模拟器并不关心性能,因此您的选择可能归结为代码样式和可维护性的首选项.