# 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 ![](https://i.imgur.com/QE2LDDl.png) + At position denoded as $rs1'$, $rs2'$ and $rd'$, only these registers can be mentioned: ![](https://i.imgur.com/IJO2bSJ.png) ### 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. ![](https://i.imgur.com/U5XbzXk.png) ![](https://i.imgur.com/SA2EcIH.png) # 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?