为riscv64-gnu-gcc添加RV32IM自定义指令编译报错求助
RV32IM架构自定义指令编译报错原因解析
基本信息
- 系统环境:Ubuntu 20.04
- 工具链版本:riscv64-gnu-toolchain 12.2.0
- 需求:为RV32IM架构的C程序添加自定义指令
custom
操作流程
- 修改指令定义文件:
- 在
/home/ubuntu2/riscv-gnu-toolchain/binutils/gdb/opcodes/riscv-opc.c中添加:{"custom", 32, INSN_CLASS_I, "d,s,t", MATCH_CUSTOM, MASK_CUSTOM, match_opcode, 0} - 在
~/riscv-opc.h中添加:#define MATCH_CUSTOM 0x700b #define MASK_CUSTOM 0xfe00707f DECLARE_INSN(custom, MATCH_CUSTOM, MASK_CUSTOM)
- 在
- 重新编译工具链:
cd riscv-gnu-toolchain make clean make build-binutils - 编译测试代码
custom_.c:
测试代码:cd /home/sample_code riscv64-unknown-linux-gnu-gcc -march=rv32im -mabi=ilp32 custom_.cint main(void){ asm("custom a1, a2, a3"); }
报错信息
custom.c:2: Error: unrecognized opcode `custom a1,a2,a3'
核心报错原因
指令类别与操作数格式不匹配
你将custom指令归类为INSN_CLASS_I(I类指令),但I类指令的标准格式是opcode rd, rs1, imm(目标寄存器、源寄存器、立即数),而测试代码中使用了三个寄存器操作数a1,a2,a3,完全不符合I类指令的参数规则。如果自定义指令需要三个寄存器,应将类别改为INSN_CLASS_R(R类指令格式:opcode rd, rs1, rs2)。参数字符串定义错误
你给I类指令指定的参数字符串是"d,s,t",其中t代表第二个源寄存器(仅R类指令支持),I类指令的参数字符串应该用"d,s,i"(i代表立即数),这种矛盾的定义会导致汇编器无法正确解析指令参数。MATCH与MASK编码不符合RISC-V规范
RV32架构的自定义指令有固定的编码区间,比如Custom-0指令的opcode字段需落在0x00或0x01范围,你设置的MATCH_CUSTOM 0x700b和MASK_CUSTOM 0xfe00707f未遵循该规范,导致汇编器无法识别这是合法的自定义指令编码。工具链未正确替换
执行make build-binutils后,新编译的汇编器可能未被安装到当前环境的有效路径中,你调用的riscv64-unknown-linux-gnu-gcc仍在使用旧版本的汇编器,自然无法识别新添加的指令。可通过riscv64-unknown-linux-gnu-as --version检查版本,确认是否为修改后重新编译的版本。
内容的提问来源于stack exchange,提问作者riddles vann
相关产品推荐
相关产品推荐

