4
votes

I am confused. When I assemble compressed instruction subset in the binary file I get the 32-bit instruction, but I thought I would get 16-bit instructions because RVC subset is encoded with 16-bits. Do the instructions from RVC(compressed) subset always extend into 32-bit instructions after assembling or they are supposed to be 16-bits long? This is written in the official instruction set manual for RISC-V:

RVC was designed under the constraint that each RVC instruction expands into one of the base RISC-V instructions: RV32I, RV64I, or RV128I

1

1 Answers

4
votes

RVC was designed under the constraint that each RVC instruction expands into one of the base RISC-V instructions: RV32I, RV64I, or RV128I

That statement is about internal implementation techniques of the chip — it allows the chip designer to do a 1:1 mapping of compressed instructions into the equivalent 32-bit instruction, meaning that the compressed instructions would have no other implications on the hardware past this mapper, i.e. no implications on the decode (modulo the mapper), no implications on the register file, no implications on the execution units, pipelining bypasses & stalling, etc.  The "no implications" applies to single cycle implementations, simple pipelined implementations, as well as more complex out of order implementations.

(One of the things they are explaining here is why, for example, there is no "save/restore multiple registers" instruction in the compressed instruction set, as such could offer decent compression for that.  However, it would add a requirement for additional state not already provided in the base instruction set.)

Some toolchains appear not to properly work with compressed instruction.

I'm using SiFive's rv64elf-gcc and it works well, with the -mabi=ilp32 -march=rv32imac options. (for reference: riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc)


test.c:

    int foo(int a) { return a+1; }

commands:

$ riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc test.c -o test.o -mabi=ilp32 -march=rv32imac -c -O3

$ riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-objdump -D test.o

test.o (-O3):

...
Disassembly of section .text:

00000000 <foo>:
   0:   0505                    addi    a0,a0,1   # 2 byte instruction
   2:   8082                    ret               # 2 byte instruction
...

test.o (no optimization):

...
Disassembly of section .text:

00000000 <foo>:
   0:   1101                    addi    sp,sp,-32
   2:   ce22                    sw      s0,28(sp)
   4:   1000                    addi    s0,sp,32
   6:   fea42623                sw      a0,-20(s0)   # 4 byte instruction
   a:   fec42783                lw      a5,-20(s0)   # 4 byte instruction
   e:   0785                    addi    a5,a5,1
  10:   853e                    mv      a0,a5
  12:   4472                    lw      s0,28(sp)
  14:   6105                    addi    sp,sp,32
  16:   8082                    ret
...