我正在寻求有关我要添加到riscv
的扩展名的帮助。
我的工作基准是riscv-tools
repo的克隆,其中包含常用工具,其中包括:
nb:我从中克隆的最后一个提交是c6d58cecb3862deb742e1a5cc9d1c682f2c50ba9
(2018-04-24)。
我的工作基于riscv32-ima
内核。我想向该处理器的ISA
添加一条指令,以激活处理器中的特定组件。
从proc本身的行为来看,我没有问题:我修改了峰值,并且我的指令(以及我添加到处理器中的组件)运行得很好。
在汇编器中,指令如下:
addi a0, a0, 0
... // other code
setupcomp // activate my component ...
... // other code
请注意,此指令没有任何操作数。
我躲开了一段时间,发现this tutorial有点老了。
所以,我:
riscv-tools/riscv-opcodes/
将opcode
及其掩码添加到riscv-tools/riscv-opcodes/opcodes
。我的看起来像这样:
setupcomp 31..28=ignore 27..20=ignore 19..15=ignore 14..12=0 11..7=ignore 6..2=0x1a 1..0=3
从那里,我重建必要的.h
文件:
make install
现在,我将必要的stucts
添加到riscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h
,并正式声明了该指令:
#define MATCH_SETUPCOMP 0x6b
#define MASK_SETUPCOMP 0x707f
DECLARE_INSN(setupcomp, MATCH_SETUPCOMP, MASK_SETUPCOMP)
这些值,我是从操作码项目中生成的。
我还将必要的定义添加到:
riscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/opcodes/riscv-opc.c
:
{"setupcomp", "I", "", MATCH_SETUPCOMP, MASK_SETUPCOMP, match_opcode, 0 },
现在,到现在为止,我相信我已经完成了所有必要的工作。我仍然对我想要的操作码有疑问,但是我不认为这会对我观察到的行为和现在描述的行为产生影响。
当我用riscv-tools/build-rv32ima.sh script
构建所有内容时,在过程即将结束时(我相信测试套件之类的东西),我收到一条消息,抱怨:
Assembler messages:
Error: internal: bad RISC-V opcode (bits 0xffffffffffff8f80 undefined): setupcomp
Fatal error: Broken assembler. No assembly attempted.
make[6]: *** [lib_a-dummy.o] Error 1
我认为我在指令的声明中缺少某些内容,可能是该声明未正确“转发”到实际需要它的工具链的每个部分。 但是我找不到哪里/什么/如何/何时,对此我将不胜感激。
当然,我很可能会缺少一些明显的东西,所以请保持谦逊:)
答案 0 :(得分:0)
向工具链添加自定义指令的最佳选择是使用我们的const readline = require('readline');
x = [];
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What do you think of Node.js? ', (answer) => {
// TODO: Log the answer in a database
rl.close();
x.push(answer);
console.log(x[0]);
});
汇编程序指令。虽然这不能给您带来漂亮的语法(应该使用预处理器宏或C包装函数),但确实可以避免碰到很多问题的工具链。
关于此问题的最佳文档是the GAS testsuite for .insn
。基本上,用户可以发出RISC-V ISA手册定义的任何格式的指令,并带有直接填写每个位模式的选项。它与GCC的内联汇编寄存器分配框架完全集成在一起,与其他指令一样工作。
答案 1 :(得分:0)
只需运行以下命令来解析MASK / MATCH:
cat opcodes-pseudo opcodes opcodes-rvc opcodes-rvc-pseudo opcodes-custom | ./parse-opcodes -c > ~/temp.h
它为riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h
提供了正确的MASK和MATCH
现在重新编译就可以了!
答案 2 :(得分:0)
正如Domso所说,riscv-opc.c
似乎要求显式屏蔽不是参数的每一位。但是,如果您在ignore
文件中将位设置为opcodes
,则parse-opcodes
生成的掩码将不会设置这些位。确实这就是您想要的,因为掩码应该表明设置的位是操作码的一部分。
由于fence.i
使用被忽略的位,因此您可以通过查看定义的方式来推导如何处理被忽略的位:
在riscv-opc.h
中,MASK_FENCE_I
只是由parse-opcodes
生成的掩码:
#define MATCH_FENCE_I 0x100f
#define MASK_FENCE_I 0x707f
DECLARE_INSN
的掩码始终不变:
DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
但是在riscv-opc.c
中,被忽略的位使用按位或屏蔽。
{"fence.i", "I", "", MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 }
由于fence.i
不带参数,因此等效于
{"fence.i", "I", "", 0xFFFFFFFF, match_opcode, 0 }
因此,您应该将MASK_SETUPCOMP
保持原样,以便可以将其分配给DECLARE_INSN
,但请将riscv-opc.c
中的掩码设置为0xFFFFFFFF
。同样,由于MASK_SETUPCOMP
被make install
复制到一堆头文件中,因此最好保持一致。