我有一个用LLVM编写的编译器,我正在寻找我的ABI遵从性。例如,我发现很难在Windows或x86上实际找到C的规范文档。我发现的解释用的是RAX/EAX/etc,而不是我可以使用的IR术语。
到目前为止,我想我已经认为LLVM以不明显的方式对待聚合--也就是说,它将它们的成员视为每个单独的参数。例如,在Windows x64上,如果我想像文档所说的那样处理一个聚合,我需要强制使用这个大小的整数,如果是8位、16位、32位或64位。否则,按指针传递。
对于x86,__cdecl和__stdcall似乎不需要我的任何操作,因为所有参数都在堆栈上传递。__fastcall说前两个32位或更小的参数是通过寄存器传递的,所以我需要强制这个大小或更小的集合。__thiscall将其传递到寄存器中,其余部分则在堆栈上传递,因此这里似乎不需要执行任何调整。
对于__vectorcall,通过整数强制传递聚合的大小不超过(void*)。对于其他聚合,如果它们是HVAs,则按值传递;否则在x86上传递值,或者在x64上传递指针。
这看起来很简单(嗯,相对地),但是sext的LLVM文档清楚地声明“这向代码生成器表明参数或返回值应该由调用方(参数)或被调用者(返回值)扩展到目标的ABI (通常是32位)所要求的范围。”用于x86调用约定的Microsoft页面没有提到将任何内容扩展到任何宽度。
我观察到了Clang生成的LLVM,它在Windows上生成byval属性。我从上面收集到的理解从来不需要使用byval。
我将如何将各种平台C ABI降低到LLVM IR?
发布于 2014-08-05 17:19:01
我不能说我100%理解你的问题,但值得注意的是,LLVM IR并不能代表平台ABI的所有微妙之处。因此,在Clang工具链中,负责执行ABI降低的是前端,例如通过值正确地将对象传递给函数等。
查看Clang源代码树中的定义lib/Basic/Targets.cpp。血淋淋的细节在lib/CodeGen/TargetInfo.cpp中有进一步的发展。
发布于 2014-08-07 22:35:34
最后,我对Clang的CodeGen内部进行了黑客攻击,以执行Clang呼叫我(C++ ABI支持已经完成)。因此,我不需要重新实现(并重新测试)他们的代码,我只是重复使用他们的工作。正式地说,CodeGen API不是公开的,也不是任何人都可以使用的,但在这种情况下,我设法使它工作。事实证明,它没有看上去那么可怕--许多类,比如LValue/RValue/ReturnValueSlot,只是在llvm::Value*上加上了一些额外的可选语义。
更大的问题将是创建蹦床从C ABI到我自己的ABI。CodeGenFunction接口似乎不太适合这一点。但我想我可以让它发挥作用。
https://stackoverflow.com/questions/25127874
复制相似问题