【发布时间】:2019-11-20 06:02:09
【问题描述】:
这是我在 stackoverflow 上被问到的第一个问题,所以请善待我 ;)
我是 RISC-V 和低级 C 编码的新手,我想知道如何使用 GCC C 代码操作 RISC-V CSR。
读取特定的 CSR(例如 MISA)看起来很容易:csrr rd, 0x301 是 csrrs rd, 0x301, x0 的缩写,例如可以完成与
int result;
asm("csrr %0, 0x301" : "=r"(result) : );
我怎样才能将上面的代码转换成某种具有以下接口的函数/可调用单元:int read_csr(int csr_number)?
由于 CSR 编号必须是机器码中的立即数,是否可以不即时生成代码(自修改代码)?
感谢您的回复和讨论。
约阿希姆
【问题讨论】:
-
它必须是
x0,还是让编译器为"=r选择一个任意寄存器?就像asm("csrrs rd, 0x301, %0" : "=r"(result) : );一样工作?对于第二部分,你可以使用@987654329 @ 约束以立即获取编译时常量输入。有关 GCC 狗的链接,请参阅 stackoverflow.com/tags/inline-assembly/info。 -
嗨,彼得,感谢您的回复。是的,
x0在这里有一个特殊的含义,即“不设置任何位”(x0 在 RISC-V 中硬连线为 0)。对于第二部分(使用不同的值而不是 0x301)我知道"i"构造,但不确定如何以函数的形式使用它,因为参数不是编译时常量? -
哦,我明白了,我误解了这个问题。这确实有效,您只是在询问如何将 C 中的值用于立即数。你真的希望能够循环 CSR 之类的吗?显而易见的解决方案是通过将其设为宏(例如 GNU C 语句表达式)来确保它可以内联到调用者中,这样您就可以使用“I”或预处理器技巧,或者仍然作为带有
__attribute__((always_inline))的函数,这样它就可以看到即使禁用了优化,编译时常量也是如此。那是你要找的吗?我的意思是显然你可以编写自修改代码,但是很糟糕。
标签: gcc inline-assembly riscv