我想使用模拟器在已有架构(x86)上测试一些架构更改。但是为了正确测试它们并运行基准测试,我可能不得不对指令集进行一些更改,有没有办法将这些更改添加到GCC或任何其他编译器?
答案 0 :(得分:4)
一种常见的方法是添加内联汇编,并直接对指令字节进行编码。
例如:
int main()
{
asm __volatile__ (".byte 0x90\n");
return 0;
}
将(gcc -O3)编译成:
00000000004005a0 <main>:
4005a0: 90 nop
4005a1: 31 c0 xor %eax,%eax
4005a3: c3 retq
所以只需用你的inst字节替换0x90即可。当然你不会看到常规objdump上的实际指令,程序可能不会在你的系统上运行(除非你使用其中一个nop组合),但模拟器应该识别它,如果它在那里正确实现。
请注意,当您不知道此指令时,您不能指望编译器能够很好地为您进行优化,并且如果它改变状态(寄存器,内存),您应该注意并使用内联汇编clobber / input / output选项。 ),以确保正确性。只有在必要时才使用优化。
另一种方法是在你的编译器中实现它 - 它可以在gcc中完成,但是如评论中所述,LLVM可能是最好的之一,因为它被设计为编译器开发平台,但它是仍然非常复杂,因为LLVM最适合IR优化阶段,并且在尝试修改特定于目标的后端时不太友好。
不过,它是可行的,如果您还计划让编译器决定何时发出此指令,则必须这样做。我建议从第一个选项开始,看看你的模拟器是否适用于这个添加,然后只花时间在编译器方面。
如果您决定在LLVM中实现此功能,最好的办法是将其定义为内部函数,这里有相对更多的文档 - http://llvm.org/docs/ExtendingLLVM.html
答案 1 :(得分:2)
您可以添加新指令,也可以通过修改GCC中称为“机器描述”的文件组来更改现有指令。 <target>.md
文件中的指令模式,<target>.c
文件中的某些代码,谓词,约束等。所有这些都放置在$GCCHOME/gcc/config/<target>/
文件夹中。所有这些东西都使用了从RTL生成ASM代码的步骤。您还可以通过更改一些其他常规GCC源文件,更改SSA树生成,RTL生成来更改发出指令的情况,但是所有这些都有些复杂。
一个简单的解释,是怎么回事:
https://www.cse.iitb.ac.in/grc/slides/cgotut-gcc/topic5-md-intro.pdf
答案 2 :(得分:0)
这是可行的,我已经做到了,但这很乏味。它基本上是使用现有平台作为模型将编译器移植到新平台的过程。在GCC的某个地方有一个定义指令集的文件,它在编译期间经历各种过程,生成更多的代码和数据。我做了20多年,所以我忘记了所有的细节,抱歉。