我正在为一个C程序编写一个汇编宏,并且对此我很新,我已经陷入困境。 我正在尝试编写一个宏来将数据从通用寄存器移动到专用寄存器。
我的问题是我发现将数据从GPR移动到SPR的语法需要一个恒定的SPR值,而我想使用存储在另一个寄存器中的变量。
# SPR is constant, rA is the value to be written
mtspr SPR, rA
我正在寻找这样的事情:
# rA contains the number of the SPR, and rB the value to be moved.
AWESOMEmtspr rA, rB
是否存在没有这样的宏的原因,我将如何自己制作?
非常感谢提前。
---- 编辑: ---- 现在看起来我在我的C代码中有一个巨大的开关盒,跳转到正确的mtspr-section。我有二十个部分用于读写特定的SPR:每个看起来完全一样,但是它们的值不变。
答案 0 :(得分:4)
您无法做到的原因是指令架构不接受寄存器间接作为寄存器参数的寻址模式。老实说,我从未见过这样的机器架构,因为寄存器的数量通常很小,因此寄存器被编码为指令本身的一部分。如果你真的不喜欢你已经得到的解决方案,你可以尝试自己合成指令(获取基本操作码,查看寄存器说明符的位置和OR在适当的值中),然后执行它。根据您的操作系统和编译器,这可能是不可能的(自修改代码通常是禁忌)。
如果在汇编中编写跳转表,是否会使代码更清晰?也许传入SPR说明符(假设它是一个从零开始的整数,或者可以被强制转换为一个),向左移动以获得跳转到跳转表中,然后跳转到表中,这将是
MTPSR PSRx, val
RET
MTPSR PSRx+1, val
RET
我不知道什么对你来说更“清洁”,只是想我会把它扔掉。请注意,您可能必须使用NOP填充以使所有内容对齐,我没有PowerPC手册,因此我不知道指令大小或对齐要求是什么。
答案 1 :(得分:1)
我使用stringizer宏找到了一个相当优雅的解决方案:
#define stringify(s)tostring(s)
#define tostring(s)#s
#define mfspr(rn)({unsigned int rval; \ asm volatile(“mfspr%0,”stringify(rn)\ :“= r”(rval)); RVAL;})
#define mtspr(rn,v)asm volatile(“mtspr”stringify(rn)“,%0”::“r”(v))
这是来自PowerPC的U-Boot代码。
答案 2 :(得分:0)
这似乎是一件奇怪的事情,但如果你确信你需要这样做,那么你需要实现一个跳转表或一系列条件,你可以测试rA并跳转到适当的硬盘编码mtspr
指令。您还需要考虑如何处理无效的SPR数字。