我有一个用LLVM编写的编译器,我正在寻求提高我的ABI合规性。 例如,我发现很难在Windows x86或Linux上找到C ABI的规范文档。 我发现的那些用RAX / EAX /等解释它,而不是我可以使用的IR术语。
到目前为止,我认为我认为LLVM无形地处理聚合 – 也就是说,它将每个成员视为一个独特的参数。 例如,在Windows x64上,如果我想处理像文档所说的聚合,我需要强制转换为该大小的单个整数,如8,16,32或64位。 否则,通过指针传递。
对于Windows x86,似乎__cdecl和__stdcall不需要我的任何操作,因为所有参数都在堆栈上传递。 __fastcall说前两个32位或更小的参数是寄存器传递的,所以我需要强制大小或更小的聚合。 __thiscall在寄存器中传递它,其余的在堆栈中,所以看起来我不需要在这里执行任何调整。
对于__vectorcall,通过整数强制传递不超过sizeof(void *)的聚合。 对于其他聚合,如果它们是HVA,则按值传递; else在x86上传递值或在x64上传递指针。
这似乎很简单(相对而言),但是sext
的LLVM文档明确指出“这表明代码生成器应该将参数或返回值符号扩展到目标的ABI所需的范围(通常为32位) )由调用者(对于参数)或被调用者(对于返回值)。“ x86调用约定的Microsoft页面没有提及任何扩展任何宽度的内容。
我观察到Clang生成的LLVM IR在Windows上生成了byval
属性。 我从上面收集到的理解从未要求使用byval
。
如何将各种平台C ABI降低到LLVM IR?
我不能说我理解你的问题100%,但值得注意的是LLVM IR根本无法代表平台ABI的所有细微之处。 因此,在Clang工具链中,前端负责执行ABI降低,例如通过值将对象正确传递给函数等。
查看Clang源代码树中的lib/Basic/Targets.cpp
以获取定义。 血腥细节还在lib/CodeGen/TargetInfo.cpp
我最终攻击Clang的CodeGen内部以执行C ABI呼叫我(C ++ ABI支持已经完成)。 因此,我只需重新使用他们的工作,而不必重新实现(并重新测试)他们的代码。 正式的CodeGen API不是公开的,并不是任何人都可以使用的,但在这种情况下,我设法让它工作。 事实certificate,它比它看起来要糟糕得多 – 像LValue / RValue / ReturnValueSlot这样的类只是llvm :: Value *上的包装器,并附加了一些额外的可选语义。
更有问题的是从C ABI到我自己的ABI创造蹦床。 CodeGenFunction接口似乎不太适合。 但我想我可以让它发挥作用。
以上就是c/c++开发分享C LLI与LLVM相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/562117.html