我正在为OpenRISC优化C代码,我想在寄存器中手动预先保存一些计算值,伪代码看起来像这样:
external loop
compute eight values (heavy calculations)
internal loop
use values computed above
当我查看GCC ABI for OpenRISC时,我看到了两组寄存器:callee-saved和temporary?我应该使用哪些寄存器来存储这八个值?我的意思是,哪些寄存器可以放在内联asm的破坏列表中?
我需要硬编辑寄存器,因为我们在自定义OpenRISC上运行可执行文件。
答案 0 :(得分:2)
答案是:无论你喜欢什么。
如果您使用被调用者保存寄存器,那么编译器将为您保存它们(只要您执行将它们标记为已破坏)。
如果你使用临时寄存器(a.k.a.calller-save),那么如果你进行函数调用,编译器将被强制保存它们。请注意,编译器也更喜欢将这些变量用于其他变量,因此如果你用掉了调用者保存的变量,那么它必须使用callee-save来处理其他事情,因此它可能最终会产生相同的差异。 / p>
在一天结束时,如果你正在进行繁重的计算,那么在开始之前将一些寄存器保存到堆栈中并不是一件大事。
有些寄存器包含您不得覆盖的重要值(例如堆栈指针)。其他的,比如GOT表指针则不那么重要,编译器会在你完成后恢复该值(只是确保你在此过程中不需要它。
但实际上,您不需要自己解决问题:编译器可以为您选择寄存器:
int a, b, c;
asm volatile ("whatever" : "=&w" (a), "=&w" (b), "=&w" (c));
不需要变量,但它们必须分配寄存器,因此它们可以有效地为您想要的任何内容保留寄存器。 &
表示" early-clobber",这意味着他们不能与输入寄存器共享同一个寄存器(不是我的示例显示的任何寄存器)。