【问题标题】:How to interact with RISC-V CSRs by using GCC C code?如何使用 GCC C 代码与 RISC-V CSR 交互?
【发布时间】:2019-11-20 06:02:09
【问题描述】:

这是我在 stackoverflow 上被问到的第一个问题,所以请善待我 ;)

我是 RISC-V 和低级 C 编码的新手,我想知道如何使用 GCC C 代码操作 RISC-V CSR。

读取特定的 CSR(例如 MISA)看起来很容易:csrr rd, 0x301csrrs 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


【解决方案1】:

您可以将I 约束用于直接常量参数:

inline int read_csr(int csr_num) __attribute__((always_inline)) {
    int result;
    asm("csrr %0, %1" : "=r"(result) : "I"(csr_num));
    return result; }

如果您使用不是常量表达式的参数调用它,这将失败,因为I 约束需要一个常量。

【讨论】:

  • I 约束在性能方面有什么好处?
  • 没有性能提升,它可以被认为是更干净一些,因为它让编译器/汇编器了解你在这里所做的事情。
猜你喜欢
  • 2022-11-08
  • 2023-04-10
  • 2010-12-02
  • 2022-11-20
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
相关资源
最近更新 更多