2

我正在尝试为我自己的自定义指令运行汇编代码。

代码如下

#include <assert.h>
#include <stdio.h>
#include <stdint.h>


int main() {
  uint64_t x = 123, y = 456, z = 0, a=22;
  int i;

for(i=0;i<4;i++)
{
  asm volatile ("custom0 x0, %0, %[i], 0" : : "r"(i),[i]"r"(i));
  printf("The value of i is:- %d \n",i);
  asm volatile ("custom0 %0, x0, %[i], 1" : "=r"(z) :[i]"r"(i));
  printf("The value of z %d is:- %d \n",i,z);
}

}

所以基本上上面显示的 custom0 指令的工作方式如下所示。

//             opcode
//             |               address
//             |               |
//             |               |       
asm volatile ("custom0 x0, %0, 1, 0" : : "r"(i));//for moving i to address 1
asm volatile ("custom0 %0, x0, 1, 1" : "=r"(z));//for moving contents of address 1 to z.

该指令独立工作正常,但是当我尝试参数化地址字段并在 for 循环中运行时,数据不会移动到该地址。

上述程序的输出是

The value of i is:- 0 
The value of z 0 is:- 0 
The value of i is:- 1 
The value of z 1 is:- 0 
The value of i is:- 2 
The value of z 2 is:- 0 
The value of i is:- 3 
The value of z 3 is:- 0 

如您所见, i 的值是正确的,但 z 的值始终为零。

正在使用的指令集是 RISCV ISA:- http://riscv.org/download.html#tab_spec_user_isa

4

1 回答 1

1

asm volatile ("custom0 x0, %0, %[i], 0" : : "r"(i),[i]"r"(i));

据我了解,@custom0指令(https://github.com/riscv/riscv-opcodes/blob/master/opcodes-custom)仅将 2 个寄存器作为第一个和第二个参数;第三个参数是“imm12”=立即。因此,有一种方法可以让汇编器对 x0 寄存器和 %0 (将是寄存器)进行编码,但 imm 字段应该具有“i”(立即)约束,而不是“r”(寄存器) - 检查 gcc 文档的约束:https ://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Simple-Constraints.html#Simple-Constraints

立即字段应该由汇编程序编码到命令中,它是命令二进制编码的一部分。您没有任何合法的变体来在程序的二进制代码中编码运行时变量,因此您不能int i作为"i"asm 参数传递。"i"参数只接受编译时常量

您可以将代码重写为 4 个 asm 语句,不带“i”和常量值的循环

asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(0));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(1));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(2));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(3));
于 2015-11-02T01:30:59.480 回答