1
votes

I have assembly code in which I am using RVC instructions such as:

c.j 24

and when I try to assemble it I get 32-bit machine code, but I expect to get 16-bit because it's compressed instruction. In binary file the instruction is represented with 32 bits, and the opcode of the assembled instruction corresponds to the normal RV32I instruction JAL, instead to opcode of C.JAL, which is 16bit wide. I compile it like this: riscv64-unknown-linux-gnu-gcc -c -mabi=ilp32 -march=rv32imac input.s -o output

Does anyone know how to solve this?

1
you mean you want to assemble it? use the assembler riscv64-unknown-linux-gnu-as input.s -o input.oold_timer
Yes to assembly it, but I still get the same output, 32bit long machine codemiki1307
fyi, it works properly with SiFive's riscv64-unknown-elf-gcc using -mabi=ilp32 & -march=rv32imac. (I don't have gnu gcc so didin't try that.)Erik Eidt
Thanks, but there must be a way to the same with gnu-gccmiki1307

1 Answers

0
votes

If you are using the riscv toolchain from https://github.com/riscv/riscv-gnu-toolchain. It is normal you are getting 32 bits version. In the binutils, you can see in the assembler porting tc-riscv.c that the assembler Expand the RVC branch into a RISC-V one. If it cant validate that the range will be respected.

When you use c.j 24 the assembler have no idea where the code will be placed and convert it to j. This is a safe approach, otherwise if a compressed instruction is emitted, the linker will have to handle this case with relax or it will issue an error if it cannot handle this case or in the worst case the generated code will be incorrect.