如何使用GCC C代码与RISC-V CSR交互?

如何使用GCC C代码与RISC-V CSR交互?,gcc,inline-assembly,riscv,Gcc,Inline Assembly,Riscv,这是我在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\u csr(int csr\u n

这是我在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\u csr(int csr\u number)

由于CSR编号必须是机器代码中的立即值,是否可以不动态生成代码(自修改代码)

感谢您的回复和讨论


Joachim

您可以对立即常数参数使用
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
约束需要常量。

它必须是
x0
,还是可以让编译器为
“=r
”选择任意寄存器?类似于
asm(“csrrs rd,0x301,%0”:“=r”(结果):)工作?对于第二部分,您可以使用
“i”
约束获取编译时常量输入作为立即数。查看GCC狗的链接。嗨,彼得,谢谢你的回复。是的,
x0
在这里有一个特殊的含义,即“不要设置任何位”(在RISC-V中,x0硬连线为0)。对于第二部分(使用不同的值而不是0x301),我知道
“I”
构造,但不确定如何以函数的形式使用它,因为参数不是编译时常量?哦,我明白了,我误解了这个问题。这是可行的,你只是在问如何使用C中的值作为立即数。你真的想在CSR上循环吗?显而易见的解决方案是通过将其设置为宏(例如GNU C语句表达式)来确保它可以内联到调用方中,这样您就可以使用“I”或预处理器技巧,或者仍然作为具有
\uu属性的函数((始终内联))
,这样即使禁用了优化,它也可以看到编译时常量。这就是你要找的吗?我的意思是,很明显,你可以编写自我修改的代码,但是很糟糕。
I
约束在性能方面有什么好处?