# RISC-V Compressed Instruction Support for rv32emu-next
###### tags: `RISC-V`
## Introuction
[Computer Archiecture 2020: Term Project](https://hackmd.io/@sysprog/arch2020-projects)
[Github](https://github.com/ccs100203/rv32emu-next/tree/shao)
[RISCV SPEC](https://riscv.org/wp-content/uploads/2019/06/riscv-spec.pdf)
We sent a pull request to the [rv32emu-next](https://github.com/sysprog21/rv32emu-next) and continuing to improve it.
## Constrains for 16-bit and 32-bit instructions
+ Bit [1:0] of 16-bit instructions **must not be `11`.**
+ Bit [4:2] of 32-bit instructions **must not be `111`**, together,
Bit [1:0] **must be `11`**
Instructions satisfying any of the following rules are illegal:
+ `[15:0]` all being 0
+ `[ILEN-1:0]` all being 1, with `ILEN` being the length of instruction
## Instruction Formats

+ At position denoded as $rs1'$, $rs2'$ and $rd'$,
only these registers can be mentioned:

### C-Instruction Segment Masks
```cpp
// ....xxxx....xxxx....xxxx....xxxx
FC_OPCODE = 0b00000000000000000000000000000011,
FC_FUNCT3 = 0b00000000000000001110000000000000,
FCR_FUNCT4 = 0b00000000000000001111000000000000,
// ....xxxx....xxxx....xxxx....xxxx
FC_RS1C = 0b00000000000000000000001110000000,
FC_RS2C = 0b00000000000000000000000000011100,
FC_RS1 = 0b00000000000000000000111110000000,
FC_RS2 = 0b00000000000000000000000001111100,
// ....xxxx....xxxx....xxxx....xxxx
FC_RDC = 0b00000000000000000000000000011100,
FC_RD = 0b00000000000000000000111110000000,
// ....xxxx....xxxx....xxxx....xxxx
FC_IMM_12_10 = 0b00000000000000000001110000000000, // CL,CS,CB
FC_IMM_6_5 = 0b00000000000000000000000001100000,
// ....xxxx....xxxx....xxxx....xxxx
FCI_IMM_12 = 0b00000000000000000001000000000000,
FCI_IMM_6_2 = 0b00000000000000000000000001111100,
// ....xxxx....xxxx....xxxx....xxxx
FCSS_IMM = 0b00000000000000000001111110000000,
// ....xxxx....xxxx....xxxx....xxxx
FCJ_IMM = 0b00000000000000000001111111111100,
// ....xxxx....xxxx....xxxx....xxxx
```
### C-Instruction Segment Decoding
```cpp=
static inline uint16_t c_dec_rs1(uint16_t c_inst){
return (uint16_t)((inst & FC_RS1) >> 7U);
}
static inline uint16_t c_dec_rs2(uint16_t c_inst){
return (uint16_t)((inst & FC_RS2) >> 2U);
}
static inline uint16_t c_dec_rd(uint16_t c_inst){
return (uint16_t)((inst & FC_RD) >> 2U);
}
static inline uint16_t c_dec_rs1c(uint16_t c_inst){
return (uint16_t)((inst & FC_RS1C) >> 7U);
}
static inline uint16_t c_dec_rs2c(uint16_t c_inst){
return (uint16_t)((inst & FC_RS2C) >> 2U);
}
static inline uint16_t c_dec_rdc(uint16_t c_inst){
return (uint16_t)((inst & FC_RDC) >> 2U);
}
```
## RVC Instruction Set Listings
We still don't support float-relating instructions.


# Current Code Standing
```cpp=
static bool c_op_addi(struct riscv_t *rv, uint16_t inst)
{
const uint16_t imm = (uint16_t)(((inst & FCI_IMM_12) >> 5) | (inst & FCI_IMM_6_2)) >> 2;
const uint16_t rd = c_dec_rd(inst);
// dispatch operation type
if(rd != 0){
// C.ADDI
rv->X[rd] += imm;
}else {
// C.NOP
}
// step over instruction
rv->PC += rv->inst_len;
// enforce zero register
if (rd == rv_reg_zero)
rv->X[rv_reg_zero] = 0;
return true;
}
```
# Problems
+ Why some instructions hold a false return value?