'Custom Instruction crashing with SIGNAL 4 (Illegal Instruction): RISC-V (32) GNU-Toolchain with QEMU
I have been wanting to develop and understand the process of creating custom extensions for a large-scale task I have, involving RISC-V compilation using the QEMU emulator. I have been loosely following the below guide: https://chowdera.com/2021/04/20210430120004272q.html - In trying to understand where and how the instruction is parsed, implemented and executed in this way through QEMU. I have edited and created an entry for my R-type instruction, same as up there, however when I try to issue it as an .insn directive in ASM, the following exception is thrown:
'Program stopped with Signal 4 (Illegal Instruction)'
The code that produced this exception:
#include <stdio.h>
static int custom_cube(int addr)
{
int cube;
asm volatile(".insn r 0x7b, 6, 6, %0, %1, x0" : "=r"(cube) : "r"(addr));
return cube;
}
int main() {
int a = 3;
int ret = 0;
ret = custom_cube((int)&a);
if(ret == a * a * a) {
printf("Success");
}
else {
printf("Failed");
}
return 0;
}
I have attempted to look into the encoding of the instruction (exactly as the tutorial describes and same opcode and bitfields), to see if there was any conflict, if the helper functions were incorrectly implemented etc, I also rebuilt and configured QEMU after implementation and ran again, reaching the same error, I changed the encoding once again to something different and changed the .insn opcode call accordingly, and attained the same behaviour, even after verifying and type-checking. I am still rather new to the build process of implementing custom RISC-V instructions specifically through QEMU, and would appreciate if there was any input or anything that either I or perhaps this tutorial has neglected to include in this process, a similar guide using the RiscFree IDE had a similar process, (implementing trans and helper functions - then rebuilding QEMU and running), so the fact the Linux kernel is throwing this exception I am still unsure of. Is there something blindingly obvious I might have missed? Should I have rebuilt the entire toolchain and not just QEMU? From what this tutorial had gathered to me, I presumed nothing further was required.
Disassembly under the custom header: With the corresponding source
static int custom_cube(int addr)
{
1018c: fd010113 addi sp,sp,-48
10190: 02812623 sw s0,44(sp)
10194: 03010413 addi s0,sp,48
10198: fca42e23 sw a0,-36(s0)
int cube;
asm volatile (
1019c: fdc42783 lw a5,-36(s0)
101a0: 0c07e7fb .4byte 0xc07e7fb
101a4: fef42623 sw a5,-20(s0)
".insn r 0x7b, 6, 6, %0, %1, x0"
:"=r"(cube)
:"r"(addr)
);
return cube;
101a8: fec42783 lw a5,-20(s0)
}
101ac: 00078513 mv a0,a5
101b0: 02c12403 lw s0,44(sp)
101b4: 03010113 addi sp,sp,48
101b8: 00008067 ret
(Since it doesn't appear to disassemble under an existing RISC-V instruction, I ((presume)) that I did put it under a free spot? I changed the variation a fair few times and still experienced this, even after validating all other possible overlaps - none were found, so I feel as if it is to do with the implementation or it's call).
UPDATE TO ISSUE: I have since used a different encoding for the instruction OPCODE = "0110011", FUNCT3 = "111" and FUNCT7 = "0100000".
Upon recompiling QEMU and running this using the .insn directive, QEMU appears to just hang upon decoding the instruction - I am unsure what further implementation is required after using TCG directives.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|