3

我正在为 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 部分。我有二十几个部分用于读写特定的 SPR:s,每个部分看起来完全相同,但有一个常数值不同。

4

3 回答 3

4

你不能这样做的原因是指令架构不接受寄存器间接作为寄存器参数的寻址模式。老实说,我从未见过这样的机器架构,因为寄存器的数量通常相当少,所以寄存器被编码为指令本身的一部分。如果你真的不喜欢你得到的解决方案,你可以尝试自己合成指令(获取基本操作码,查看寄存器说明符的位置和适当的值),然后执行它。根据您的操作系统和编译器,这可能是不可能的(自修改代码通常是禁忌)。

如果您在汇编中编写跳转表,是否会使代码更清晰?也许传入 SPR 说明符(假设它是一个从零开始的整数,或者可以强制转换为 1),将其向左移动以获得跳转表的偏移量,然后跳转到表中,这将是一个序列

MTPSR PSRx, val
RET
MTPSR PSRx+1, val
RET

我不知道什么对你来说算“更干净”,只是想我会把它扔掉。请注意,您可能必须使用 NOP 填充以使所有内容对齐,我没有 PowerPC 手册,因此我不知道指令大小或对齐要求是什么。

于 2010-07-13T14:19:18.577 回答
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 代码。

于 2011-04-13T21:18:19.727 回答
0

这似乎是一件奇怪的事情,但是如果您确信出于某种原因需要这样做,那么您将需要实现一个跳转表或条件序列,从而测试 rA 并跳转到适当的硬编码mtspr指令. 您还需要考虑如何处理无效的 SPR 编号。

于 2010-07-13T13:40:04.977 回答