Introduction

The compressed instruction set RV64C uses bits [1:0] != 0b11 to determine a quadrant. When these bits are not 0b11, this means that the instruction is 16-bits. RV64C instructions can be mixed with the traditional, 32-bit instructions. Therefore, before decoding, you must check bits [1:0] to determine if you need to load 16 or 32 bits. Luckily, the instructions are in little-endian format, so for both 16 and 32-bits, you need to grab the first byte and check bits 1:0. If they both are 1, you need to grab three more bytes. If they are not, then you need to grab one more byte.

Implementing RV64C is probably the most challenging aspect of this project, which is why it accounts for so many points, but it is an option.


Instruction Types

RV64C has several instruction types, and the format is ‘weird’ to say the least. This is mainly to account for the much shorter instruction size.

RV64C instruction types.

You can see that we have both rs1 and rs1′ as well as rd and rd’. Notice that rd is 5 bits, just like normal, but rs1′ and rd’ are both 3 bits, meaning that only some registers are available. For the 3-bit version, the register is a lookup table, however, if you look at the table, it’s just the 3 bits added to 8.

RV64C ‘prime’ register translation table.

Instruction Set

The sub-group (called a quadrant in the manual–even though there are only three of them) is based on bits [1:0].

instruction[1:0] = 0b00
instruction[1:0] = 0b01
instruction[1:0] = 0b10

Stack Pointer Based Loads and Stores


Control Transfer Instructions


Integer Computation


Register-to-Register Instructions


RV64C Opcode Map

You probably don’t need this table, but it might be useful for verifying your code.