使用GCC内联ARM汇编时优化已使用的寄存器

5
我想在C代码中编写一些内联ARM汇编。对于这段代码,我需要使用一个或两个不仅仅是作为输入和输出声明的寄存器来进行操作。我知道如何使用clobber列表告诉GCC我将使用一些额外的寄存器来完成计算。
然而,我确信GCC在优化时可以随意调整使用哪些寄存器。也就是说,我觉得使用固定的寄存器进行计算是不好的选择。
那么,在没有使用固定寄存器的情况下,使用一些额外的既不是输入也不是输出的寄存器的最佳方法是什么?
附言:我考虑使用一个虚拟的输出变量可能会起到作用,但我不确定那样做会有什么奇怪的其他影响...

我敢打赌这是相当直接的,但我会让一位C语言大师来回答这个问题。 :-) - Noldorin
1
我知道你可以使用寄存器别名,让编译器选择要使用的寄存器,但是我忘记了语法。或者你可以下定决心,只需编写一个.s文件并单独汇编它以获得更大的灵活性。 - Michael Dorgan
1
@MichaelDorgan 感谢您的建议。我知道输入和输出寄存器是这样工作的,但我还没有看到它用于临时寄存器。您提供的第二个解决方案有点相反于我需要的,它会删除更多的优化选项(指定输入和输出寄存器)。 - Madcowswe
如果您编写自己的.s文件,您将处理自己的优化。您控制推送和弹出以及在何处使用哪些内容,只需确保遵循ARM寄存器保护规则即可。 - Michael Dorgan
你的意思是我要用汇编语言编写整个程序吗?呵呵,那肯定是最后的选择了 ;D - Madcowswe
1个回答

5

好的,我找到了一份支持使用虚拟输出而不是硬寄存器的来源:

4.8 临时寄存器: 有些人错误地使用破坏描述符来表示临时寄存器。正确的方法是编写一个虚拟输出,并根据输入允许的重叠情况使用“=r”或“=&r”。GCC为虚拟值分配一个寄存器。区别在于GCC可以选择一个方便的寄存器,因此具有更大的灵活性。

来自这个pdf的第20页。

对于任何对GCC内联汇编感兴趣的人,这个网站非常有教育意义。


上周在AArch64上,我发现当我硬编码(如实际编写add w2, %[input1], %[input2])临时值并损坏它们时,gcc生成了更好的代码,在封头和尾部的汇编中。比起使用你提到的技巧(如add %[fakeoutputastemp], %[input1], %[input2])。当然,你的结果可能会有所不同。我的情况:https://dev59.com/NYfca4cB1Zd3GeqPkIuY。如果你知道调用约定,你可以选择不会导致参数被推送、也不太高的临时寄存器。 - ahcox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接