From 6932a6bc4b1c60f6ce3e594cb97312c06c077663 Mon Sep 17 00:00:00 2001 From: Uduru Date: Mon, 4 Jan 2021 21:26:28 +0800 Subject: [PATCH 01/29] Modified .gitignore for testing files --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 5d0f8f0b..779f479d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,7 @@ build/DOOM1.WAD* build/rv32emu *.o *.o.d + +# Added by Uduru0522 +test/ +.vscode \ No newline at end of file From fbbe1d7b9b24119c4893d9c625c4531a93a2e964 Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Tue, 5 Jan 2021 01:54:12 +0800 Subject: [PATCH 02/29] Revise PC, Add Inst. Table & Inst. Distinguishment In `riscv_private.h`: - Add variable `inst_len` in structure `riscv_t` to record length of current instruction - Add mask for compressed instruction opcode In `riscv.c`: - Add function table `c_opcodes`, defined `NULL` - Modify `rv_step()` to process compressed instructions --- riscv.c | 77 ++++++++++++++++++++++++++++++++++++++++--------- riscv_private.h | 10 +++++++ 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/riscv.c b/riscv.c index 71465a9c..ba1e49bf 100644 --- a/riscv.c +++ b/riscv.c @@ -21,7 +21,7 @@ static void rv_except_inst_misaligned(struct riscv_t *rv, uint32_t old_pc) rv->PC = base; break; case 1: // VECTORED - rv->PC = base + 4 * code; + rv->PC = base + rv->inst_len * code; break; } @@ -43,7 +43,7 @@ static void rv_except_load_misaligned(struct riscv_t *rv, uint32_t addr) rv->PC = base; break; case 1: // VECTORED - rv->PC = base + 4 * code; + rv->PC = base + rv->inst_len * code; break; } @@ -65,7 +65,7 @@ static void rv_except_store_misaligned(struct riscv_t *rv, uint32_t addr) rv->PC = base; break; case 1: // VECTORED - rv->PC = base + 4 * code; + rv->PC = base + rv->inst_len * code; break; } @@ -123,7 +123,7 @@ static bool op_load(struct riscv_t *rv, uint32_t inst UNUSED) return false; } // step over instruction - rv->PC += 4; + rv->PC += rv->inst_len; // enforce zero register if (rd == rv_reg_zero) rv->X[rv_reg_zero] = 0; @@ -187,7 +187,7 @@ static bool op_op_imm(struct riscv_t *rv, uint32_t inst) } // step over instruction - rv->PC += 4; + rv->PC += rv->inst_len; // enforce zero register if (rd == rv_reg_zero) @@ -204,7 +204,7 @@ static bool op_auipc(struct riscv_t *rv, uint32_t inst) rv->X[rd] = val; // step over instruction - rv->PC += 4; + rv->PC += rv->inst_len; // enforce zero register if (rd == rv_reg_zero) @@ -249,7 +249,7 @@ static bool op_store(struct riscv_t *rv, uint32_t inst) } // step over instruction - rv->PC += 4; + rv->PC += rv->inst_len; return true; } @@ -380,7 +380,7 @@ static bool op_op(struct riscv_t *rv, uint32_t inst) return false; } // step over instruction - rv->PC += 4; + rv->PC += rv->inst_len; // enforce zero register if (rd == rv_reg_zero) rv->X[rv_reg_zero] = 0; @@ -395,7 +395,7 @@ static bool op_lui(struct riscv_t *rv, uint32_t inst) rv->X[rd] = val; // step over instruction - rv->PC += 4; + rv->PC += rv->inst_len; // enforce zero register if (rd == rv_reg_zero) @@ -446,7 +446,7 @@ static bool op_branch(struct riscv_t *rv, uint32_t inst) rv_except_inst_misaligned(rv, pc); } else { // step over instruction - rv->PC += 4; + rv->PC += rv->inst_len; } // can branch return false; @@ -462,7 +462,7 @@ static bool op_jalr(struct riscv_t *rv, uint32_t inst) const int32_t imm = dec_itype_imm(inst); // compute return address - const uint32_t ra = rv->PC + 4; + const uint32_t ra = rv->PC + rv->inst_len; // jump rv->PC = (rv->X[rs1] + imm) & ~1u; @@ -488,7 +488,7 @@ static bool op_jal(struct riscv_t *rv, uint32_t inst) const int32_t rel = dec_jtype_imm(inst); // compute return address - const uint32_t ra = rv->PC + 4; + const uint32_t ra = rv->PC + rv->inst_len; rv->PC += rel; // link @@ -654,7 +654,7 @@ static bool op_system(struct riscv_t *rv, uint32_t inst) } // step over instruction - rv->PC += 4; + rv->PC += rv->inst_len; // enforce zero register if (rd == rv_reg_zero) @@ -770,8 +770,34 @@ static bool op_amo(struct riscv_t *rv, uint32_t inst) #define op_nmsub NULL #define op_nmadd NULL +/* TODO: function implemetation */ +#define c_op_addi4spn NULL +#define c_op_addi NULL +#define c_op_slli NULL +#define c_op_fld NULL +#define c_op_jal NULL +#define c_op_fldsp NULL +#define c_op_lw NULL +#define c_op_li NULL +#define c_op_lwsp NULL +#define c_op_flw NULL +#define c_op_lui NULL +#define c_op_flwsp NULL +#define c_op_misc_alu NULL +#define c_op_jalr NULL +#define c_op_fsd NULL +#define c_op_j NULL +#define c_op_fsdsp NULL +#define c_op_sw NULL +#define c_op_beqz NULL +#define c_op_swsp NULL +#define c_op_fsw NULL +#define c_op_bnez NULL +#define c_op_fswsp NULL + // opcode handler type typedef bool (*opcode_t)(struct riscv_t *rv, uint32_t inst); +typedef bool (*c_opcode_t)(struct riscv_t *rv, uint16_t inst); // clang-format off // opcode dispatch table @@ -782,6 +808,18 @@ static const opcode_t opcodes[] = { op_madd, op_msub, op_nmsub, op_nmadd, op_fp, NULL, NULL, NULL, // 10 op_branch, op_jalr, NULL, op_jal, op_system, NULL, NULL, NULL, // 11 }; + +static const c_opcode_t c_opcodes[] = { +// 00 01 10 11 + c_op_addi4spn, c_op_addi, c_op_slli, NULL, // 000 + c_op_fld, c_op_jal, c_op_fldsp, NULL, // 001 + c_op_lw, c_op_li, c_op_lwsp, NULL, // 010 + c_op_flw, c_op_lui, c_op_flwsp, NULL, // 011 + NULL, c_op_misc_alu, c_op_jalr, NULL, // 100 + c_op_fsd, c_op_j, c_op_fsdsp, NULL, // 101 + c_op_sw, c_op_beqz, c_op_swsp, NULL, // 110 + c_op_fsw, c_op_bnez, c_op_fswsp, NULL, // 111 +}; // clang-format on void rv_step(struct riscv_t *rv, int32_t cycles) @@ -800,6 +838,7 @@ void rv_step(struct riscv_t *rv, int32_t cycles) // dispatch this opcode const opcode_t op = opcodes[index]; assert(op); + rv->inst_len = INST_32; if (!op(rv, inst)) break; @@ -807,7 +846,16 @@ void rv_step(struct riscv_t *rv, int32_t cycles) rv->csr_cycle++; } else { // TODO: compressed instruction - assert(!"Unreachable"); + const uint16_t c_index = (inst & FR_C_15_13 >> 11) | (inst & FR_C_1_0); + // TODO: table implement + const c_opcode_t op = c_opcodes[c_index]; + assert(op); + rv->inst_len = INST_16; + if (!op(rv, inst)) + break; + + // increment the cycles csr + rv->csr_cycle++; } } } @@ -891,6 +939,7 @@ void rv_reset(struct riscv_t *rv, riscv_word_t pc) // set the reset address rv->PC = pc; + rv->inst_len = INST_UNKNOWN; // set the default stack pointer rv->X[rv_reg_sp] = DEFAULT_STACK_ADDR; diff --git a/riscv_private.h b/riscv_private.h index 99d84bf5..06f9e5ce 100644 --- a/riscv_private.h +++ b/riscv_private.h @@ -77,6 +77,9 @@ enum { FR4_FMT = 0b00000110000000000000000000000000, // r4-type FR4_RS3 = 0b11111000000000000000000000000000, // ....xxxx....xxxx....xxxx....xxxx + FR_C_1_0 = 0b00000000000000000000000000000011, // C-instuction + FR_C_15_13 = 0b00000000000000001110000000000000, + // ....xxxx....xxxx....xxxx....xxxx }; // clang-format off @@ -104,6 +107,13 @@ struct riscv_t { uint32_t csr_mepc; uint32_t csr_mip; uint32_t csr_mbadaddr; + + // current instruction length + enum { + INST_UNKNOWN = 0, + INST_16 = 0x02, + INST_32 = 0x04, + }inst_len; }; // decode rd field From 8874ab5c7db83be85c4a88f321551e9322e5372e Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Wed, 6 Jan 2021 01:33:42 +0800 Subject: [PATCH 03/29] Add Decoding Func., Inst. Templates & A Few Func. Definitions In riscv_private.h: - Add instruction decoding function & revise masks In io.c: - revise address check In riscv.c: - Add compressed instruction templates - Add register checking function - Implement c_op_addi(), c_op_swsp(), c_op_addi4spn(), c_op_li() --- io.c | 2 +- riscv.c | 251 +++++++++++++++++++++++++++++++++++++++++++----- riscv_private.h | 53 +++++++++- 3 files changed, 277 insertions(+), 29 deletions(-) diff --git a/io.c b/io.c index b1142aa7..88b5f29d 100644 --- a/io.c +++ b/io.c @@ -70,7 +70,7 @@ uint32_t memory_read_str(memory_t *m, uint8_t *dst, uint32_t addr, uint32_t max) uint32_t memory_read_ifetch(memory_t *m, uint32_t addr) { const uint32_t addr_lo = addr & mask_lo; - assert((addr_lo & 3) == 0); + assert((addr_lo & 1) == 0); chunk_t *c = m->chunks[addr >> 16]; assert(c); diff --git a/riscv.c b/riscv.c index ba1e49bf..9a82aa94 100644 --- a/riscv.c +++ b/riscv.c @@ -1,11 +1,20 @@ #include #include +#include #include #include #include "riscv.h" #include "riscv_private.h" +inline static void print_register(struct riscv_t *rv) +{ + for (int i = 0; i < 32; ++i) { + printf("X[%02d] = %X\t", i, rv->X[i]); + } + putchar('\n'); +} + static void rv_except_inst_misaligned(struct riscv_t *rv, uint32_t old_pc) { const uint32_t base = rv->csr_mtvec & ~0x3; @@ -770,30 +779,217 @@ static bool op_amo(struct riscv_t *rv, uint32_t inst) #define op_nmsub NULL #define op_nmadd NULL +#define ENABLE_RV32C 1 +#ifdef ENABLE_RV32C +static bool c_op_addi(struct riscv_t *rv, uint16_t inst) +{ + uint16_t tmp = + (uint16_t)(((inst & FCI_IMM_12) >> 5) | (inst & FCI_IMM_6_2)) >> 2; + const int16_t imm = (0x20 & tmp) ? 0xffc0 | tmp : tmp; + 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; +} + +static bool c_op_sw(struct riscv_t *rv, uint16_t inst) +{ + // const uint16_t imm = + // (inst & FC_IMM_12_10) >> 7 | (inst & 0x20) >> 4 | (inst & 0x10) << 1; + // const uint16_t rs1 = c_dec_rs1c(inst); + // const uint16_t rs2 = c_dec_rs2c(inst); + // printf("%x, %x, %x\n", imm, rs1, rs2); + + + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_swsp(struct riscv_t *rv, uint16_t inst) +{ + const uint16_t imm = (inst & 0x1e00) >> 7 | (inst & 0x180) >> 1; + const uint16_t rs2 = c_dec_rs2(inst); + const uint32_t addr = rv->X[2] + imm; + const uint32_t data = rv->X[rs2]; + + if (addr & 3) { + rv_except_store_misaligned(rv, addr); + return false; + } + rv->io.mem_write_w(rv, addr, data); + + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_addi4spn(struct riscv_t *rv, uint16_t inst) +{ + const uint16_t imm = (inst & 0x1800) >> 7 | (inst & 0x780) >> 1 | + (inst & 0x40) >> 4 | (inst & 0x20) >> 2; + const uint16_t rd = c_dec_rdc(inst) | 0x08; + rv->X[rd] = rv->X[2] + imm; + + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_fld(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_lw(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_flw(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_fsd(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_fsw(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_jal(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_li(struct riscv_t *rv, uint16_t inst) +{ + uint16_t tmp = (uint16_t)((inst & 0x1000) >> 7 | (inst & 0x7c) >> 2); + const int16_t imm = (0x20 & tmp) ? 0xffc0 | tmp : tmp; + const uint16_t rd = c_dec_rd(inst); + rv->X[rd] = imm; + + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_lui(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_j(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_slli(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_fldsp(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) +{ + /* TODO CURRENT FUNCTION */ + assert(0); + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_flwsp(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_jalr(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_fsdsp(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_fswsp(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + + +#endif // ENABLE_RV32C + + /* TODO: function implemetation */ -#define c_op_addi4spn NULL -#define c_op_addi NULL -#define c_op_slli NULL -#define c_op_fld NULL -#define c_op_jal NULL -#define c_op_fldsp NULL -#define c_op_lw NULL -#define c_op_li NULL -#define c_op_lwsp NULL -#define c_op_flw NULL -#define c_op_lui NULL -#define c_op_flwsp NULL -#define c_op_misc_alu NULL -#define c_op_jalr NULL -#define c_op_fsd NULL -#define c_op_j NULL -#define c_op_fsdsp NULL -#define c_op_sw NULL -#define c_op_beqz NULL -#define c_op_swsp NULL -#define c_op_fsw NULL -#define c_op_bnez NULL -#define c_op_fswsp NULL +// #define c_op_addi4spn NULL +// #define c_op_slli NULL +// #define c_op_fld NULL +// #define c_op_jal NULL +// #define c_op_fldsp NULL +// #define c_op_lw NULL +// #define c_op_lwsp NULL +// #define c_op_flw NULL +// #define c_op_lui NULL +// #define c_op_flwsp NULL +// #define c_op_misc_alu NULL +// #define c_op_jalr NULL +// #define c_op_fsd NULL +// #define c_op_j NULL +// #define c_op_fsdsp NULL +// #define c_op_beqz NULL +// #define c_op_fsw NULL +// #define c_op_bnez NULL +// #define c_op_fswsp NULL // opcode handler type typedef bool (*opcode_t)(struct riscv_t *rv, uint32_t inst); @@ -809,6 +1005,7 @@ static const opcode_t opcodes[] = { op_branch, op_jalr, NULL, op_jal, op_system, NULL, NULL, NULL, // 11 }; +// compressed opcode dispatch table static const c_opcode_t c_opcodes[] = { // 00 01 10 11 c_op_addi4spn, c_op_addi, c_op_slli, NULL, // 000 @@ -835,7 +1032,7 @@ void rv_step(struct riscv_t *rv, int32_t cycles) if ((inst & 3) == 3) { const uint32_t index = (inst & INST_6_2) >> 2; - // dispatch this opcode + // dispatch this opcode const opcode_t op = opcodes[index]; assert(op); rv->inst_len = INST_32; @@ -846,14 +1043,16 @@ void rv_step(struct riscv_t *rv, int32_t cycles) rv->csr_cycle++; } else { // TODO: compressed instruction - const uint16_t c_index = (inst & FR_C_15_13 >> 11) | (inst & FR_C_1_0); + const uint16_t c_index = + (inst & FC_FUNC3) >> 11 | (inst & FC_OPCODE); // TODO: table implement const c_opcode_t op = c_opcodes[c_index]; + printf("c_index: %d, inst: %x\n", c_index, inst); assert(op); rv->inst_len = INST_16; if (!op(rv, inst)) break; - + // increment the cycles csr rv->csr_cycle++; } diff --git a/riscv_private.h b/riscv_private.h index 06f9e5ce..03d1d130 100644 --- a/riscv_private.h +++ b/riscv_private.h @@ -77,8 +77,27 @@ enum { FR4_FMT = 0b00000110000000000000000000000000, // r4-type FR4_RS3 = 0b11111000000000000000000000000000, // ....xxxx....xxxx....xxxx....xxxx - FR_C_1_0 = 0b00000000000000000000000000000011, // C-instuction - FR_C_15_13 = 0b00000000000000001110000000000000, + FC_OPCODE = 0b00000000000000000000000000000011, // compressed-instuction + FC_FUNC3 = 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 }; // clang-format off @@ -220,3 +239,33 @@ static inline uint32_t sign_extend_b(uint32_t x) { return (int32_t)((int8_t) x); } + +// decode rs1 field +static inline uint16_t c_dec_rs1(uint16_t x){ + return (uint16_t)((x & FC_RS1) >> 7U); +} + +// decode rs2 field +static inline uint16_t c_dec_rs2(uint16_t x){ + return (uint16_t)((x & FC_RS2) >> 2U); +} + +// decode rd field +static inline uint16_t c_dec_rd(uint16_t x){ + return (uint16_t)((x & FC_RD) >> 7U); +} + +// decode rs1' field +static inline uint16_t c_dec_rs1c(uint16_t x){ + return (uint16_t)((x & FC_RS1C) >> 7U); +} + +// decode rs2' field +static inline uint16_t c_dec_rs2c(uint16_t x){ + return (uint16_t)((x & FC_RS2C) >> 2U); +} + +// decode rd' field +static inline uint16_t c_dec_rdc(uint16_t x){ + return (uint16_t)((x & FC_RDC) >> 2U); +} From 9b778a459a93d678a061912bcd8af4336c880057 Mon Sep 17 00:00:00 2001 From: Uduru Date: Wed, 6 Jan 2021 05:47:43 +0800 Subject: [PATCH 04/29] Modified Makefile to support debug build & RV32C In `Makefike`: - Added target `debug`, used to enable debug functions when building - Added `ENABLE_RV32C` flag --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index ad3a108e..b6e736c1 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ CFLAGS += -D ENABLE_Zicsr CFLAGS += -D ENABLE_Zifencei CFLAGS += -D ENABLE_RV32A CFLAGS += -D DEFAULT_STACK_ADDR=0xFFFFF000 +CFLAGS += -D ENABLE_RV32C # Experimental SDL oriented system calls CFLAGS += -D ENABLE_SDL @@ -68,4 +69,8 @@ clean: distclean: clean $(RM) $(OUT)/DOOM1.WAD $(OUT)/DOOM1.WAD.sha1 +debug: debug_setting +debug_setting: CFLAGS += -D DEBUG +debug_setting: all + -include $(deps) From 8ab1561a99c7b38005325ce8d0f73b7dff6b0c56 Mon Sep 17 00:00:00 2001 From: Uduru Date: Wed, 6 Jan 2021 06:44:41 +0800 Subject: [PATCH 05/29] Implemented c_op_lwsp(), Wrapped RV32F Instructions. In `riscv.c`: - Implemented `c_op_lwsp()` for c.lwsp instruction - Moved F-Extension related functions into #ifdef wrappers for future implementation --- riscv.c | 76 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 19 deletions(-) diff --git a/riscv.c b/riscv.c index 9a82aa94..d9d6ea2e 100644 --- a/riscv.c +++ b/riscv.c @@ -7,13 +7,25 @@ #include "riscv.h" #include "riscv_private.h" -inline static void print_register(struct riscv_t *rv) +#ifdef DEBUG +#define print_register(rv) __print_register((rv)) +inline static void __print_register(struct riscv_t *rv) { for (int i = 0; i < 32; ++i) { - printf("X[%02d] = %X\t", i, rv->X[i]); + printf("X[%02d] = %08X\t", i, rv->X[i]); + if(!(i % 5)){ + putchar('\n'); + } } putchar('\n'); } +#define debug_print(str) printf("DEBUG: " #str "\n") +#define debug_print_val(var) printf("DEBUG: " #var " = %08X(hex)\n", var) +#else +#define print_register(rv) (void)0 +#define debug_print(str) (void)0 +#define debug_print_val(var) (void)0 +#endif static void rv_except_inst_misaligned(struct riscv_t *rv, uint32_t old_pc) { @@ -779,7 +791,6 @@ static bool op_amo(struct riscv_t *rv, uint32_t inst) #define op_nmsub NULL #define op_nmadd NULL -#define ENABLE_RV32C 1 #ifdef ENABLE_RV32C static bool c_op_addi(struct riscv_t *rv, uint16_t inst) { @@ -928,27 +939,43 @@ static bool c_op_slli(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_fldsp(struct riscv_t *rv, uint16_t inst) +static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) { + debug_print("Entered c.lwsp\n"); + + uint16_t temp = 0; + temp |= ((inst & FCI_IMM_6_2 | 0b1110000) >> 2); + temp |= ((inst & FCI_IMM_12) >> 7); + temp |= ((inst & FCI_IMM_6_2 | 0b0001100) << 4); + + const uint16_t imm = temp; + const uint16_t rd = (inst & FC_RD) >> 7; + + // Get imm*4 + sp from memory + rv->X[rd] = rv->io.mem_read_w(rv, (rv->X[2] + imm)); + + if(rd == 0){ + assert(!"In c.lwsp: rd = 0 invalid.\n"); + } + rv->PC += rv->inst_len; return true; } -static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) +static bool c_op_jalr(struct riscv_t *rv, uint16_t inst) { - /* TODO CURRENT FUNCTION */ - assert(0); rv->PC += rv->inst_len; return true; } -static bool c_op_flwsp(struct riscv_t *rv, uint16_t inst) +#ifdef ENABLE_RV32F +static bool c_op_fldsp(struct riscv_t *rv, uint16_t inst) { rv->PC += rv->inst_len; return true; } -static bool c_op_jalr(struct riscv_t *rv, uint16_t inst) +static bool c_op_flwsp(struct riscv_t *rv, uint16_t inst) { rv->PC += rv->inst_len; return true; @@ -965,31 +992,34 @@ static bool c_op_fswsp(struct riscv_t *rv, uint16_t inst) rv->PC += rv->inst_len; return true; } - - +#else +#define c_op_fldsp NULL +#define c_op_flwsp NULL +#define c_op_fswsp NULL +#define c_op_fsdsp NULL +#endif // ENABLE_RV32F #endif // ENABLE_RV32C /* TODO: function implemetation */ -// #define c_op_addi4spn NULL +// #define c_op_addi4spn NULL - done / tested +// #define c_op_addi NULL - done / tested +// #define c_op_swsp NULL - done / tested +// #define c_op_li NULL - done / tested // #define c_op_slli NULL // #define c_op_fld NULL // #define c_op_jal NULL -// #define c_op_fldsp NULL // #define c_op_lw NULL // #define c_op_lwsp NULL // #define c_op_flw NULL // #define c_op_lui NULL -// #define c_op_flwsp NULL // #define c_op_misc_alu NULL // #define c_op_jalr NULL // #define c_op_fsd NULL // #define c_op_j NULL -// #define c_op_fsdsp NULL // #define c_op_beqz NULL // #define c_op_fsw NULL // #define c_op_bnez NULL -// #define c_op_fswsp NULL // opcode handler type typedef bool (*opcode_t)(struct riscv_t *rv, uint32_t inst); @@ -1028,6 +1058,9 @@ void rv_step(struct riscv_t *rv, int32_t cycles) // fetch the next instruction const uint32_t inst = rv->io.mem_ifetch(rv, rv->PC); + // Illegal instruction if inst[15:0] == 0 + assert(inst & 0xFFFF && "inst[15:0] must not be all 0.\n"); + // standard uncompressed instruction if ((inst & 3) == 3) { const uint32_t index = (inst & INST_6_2) >> 2; @@ -1042,12 +1075,14 @@ void rv_step(struct riscv_t *rv, int32_t cycles) // increment the cycles csr rv->csr_cycle++; } else { - // TODO: compressed instruction const uint16_t c_index = (inst & FC_FUNC3) >> 11 | (inst & FC_OPCODE); - // TODO: table implement const c_opcode_t op = c_opcodes[c_index]; - printf("c_index: %d, inst: %x\n", c_index, inst); + + // DEBUG: Print accepted c-instruction + debug_print_val(c_index); + debug_print_val(inst); + // printf("c_index: %d, inst: %x\n", c_index, inst); assert(op); rv->inst_len = INST_16; if (!op(rv, inst)) @@ -1055,6 +1090,9 @@ void rv_step(struct riscv_t *rv, int32_t cycles) // increment the cycles csr rv->csr_cycle++; + + // DEBUG: print register state + print_register(rv); } } } From 81b093a0f20c842d06433ef33f464540b5322fec Mon Sep 17 00:00:00 2001 From: Uduru Date: Wed, 6 Jan 2021 07:44:56 +0800 Subject: [PATCH 06/29] Implemented `c_op_lw()`, Added debug messages In `riscv.c`: - Added debug message "Entered c.XXX" to inform which function is called - Implemented `c_op_lw()` - Removed RV64 and RV128 only instructions - Moved more RV32F related instruction into #define wrapper - Added temporary variable to some function to reduce line width --- riscv.c | 166 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 66 deletions(-) diff --git a/riscv.c b/riscv.c index d9d6ea2e..101cfec5 100644 --- a/riscv.c +++ b/riscv.c @@ -794,6 +794,8 @@ static bool op_amo(struct riscv_t *rv, uint32_t inst) #ifdef ENABLE_RV32C static bool c_op_addi(struct riscv_t *rv, uint16_t inst) { + debug_print("Entered c.addi"); + uint16_t tmp = (uint16_t)(((inst & FCI_IMM_12) >> 5) | (inst & FCI_IMM_6_2)) >> 2; const int16_t imm = (0x20 & tmp) ? 0xffc0 | tmp : tmp; @@ -828,27 +830,16 @@ static bool c_op_sw(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_swsp(struct riscv_t *rv, uint16_t inst) -{ - const uint16_t imm = (inst & 0x1e00) >> 7 | (inst & 0x180) >> 1; - const uint16_t rs2 = c_dec_rs2(inst); - const uint32_t addr = rv->X[2] + imm; - const uint32_t data = rv->X[rs2]; - - if (addr & 3) { - rv_except_store_misaligned(rv, addr); - return false; - } - rv->io.mem_write_w(rv, addr, data); - - rv->PC += rv->inst_len; - return true; -} - static bool c_op_addi4spn(struct riscv_t *rv, uint16_t inst) { - const uint16_t imm = (inst & 0x1800) >> 7 | (inst & 0x780) >> 1 | - (inst & 0x40) >> 4 | (inst & 0x20) >> 2; + debug_print("Entered c.addi4spn"); + uint16_t temp = 0; + temp |= (inst & 0x1800) >> 7; + temp |= (inst & 0x780) >> 1; + temp |= (inst & 0x40) >> 4; + temp |= (inst & 0x20) >> 2; + + const uint16_t imm = temp; const uint16_t rd = c_dec_rdc(inst) | 0x08; rv->X[rd] = rv->X[2] + imm; @@ -856,24 +847,6 @@ static bool c_op_addi4spn(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_fld(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_lw(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_flw(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - static bool c_op_fsd(struct riscv_t *rv, uint16_t inst) { rv->PC += rv->inst_len; @@ -894,6 +867,8 @@ static bool c_op_jal(struct riscv_t *rv, uint16_t inst) static bool c_op_li(struct riscv_t *rv, uint16_t inst) { + debug_print("Entered c.li"); + uint16_t tmp = (uint16_t)((inst & 0x1000) >> 7 | (inst & 0x7c) >> 2); const int16_t imm = (0x20 & tmp) ? 0xffc0 | tmp : tmp; const uint16_t rd = c_dec_rd(inst); @@ -939,31 +914,77 @@ static bool c_op_slli(struct riscv_t *rv, uint16_t inst) return true; } +static bool c_op_jalr(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +// CI-type static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.lwsp\n"); + debug_print("Entered c.lwsp"); uint16_t temp = 0; - temp |= ((inst & FCI_IMM_6_2 | 0b1110000) >> 2); - temp |= ((inst & FCI_IMM_12) >> 7); - temp |= ((inst & FCI_IMM_6_2 | 0b0001100) << 4); + temp |= ((inst & FCI_IMM_6_2) | 0b1110000) >> 2; + temp |= (inst & FCI_IMM_12) >> 7; + temp |= ((inst & FCI_IMM_6_2) | 0b0001100) << 4; const uint16_t imm = temp; - const uint16_t rd = (inst & FC_RD) >> 7; - - // Get imm*4 + sp from memory - rv->X[rd] = rv->io.mem_read_w(rv, (rv->X[2] + imm)); + const uint16_t rd = c_dec_rd(inst); + const uint16_t addr = rv->X[2] + imm; - if(rd == 0){ - assert(!"In c.lwsp: rd = 0 invalid.\n"); + if(addr & 3){ + rv_except_load_misaligned(rv, addr); + return false; } + rv->X[rd] = rv->io.mem_read_w(rv, addr); rv->PC += rv->inst_len; return true; } -static bool c_op_jalr(struct riscv_t *rv, uint16_t inst) +// CSS-type +static bool c_op_swsp(struct riscv_t *rv, uint16_t inst) { + debug_print("Entered c.swsp"); + + const uint16_t imm = (inst & 0x1e00) >> 7 | (inst & 0x180) >> 1; + const uint16_t rs2 = c_dec_rs2(inst); + const uint32_t addr = rv->X[2] + imm; + const uint32_t data = rv->X[rs2]; + + if (addr & 3) { + rv_except_store_misaligned(rv, addr); + return false; + } + rv->io.mem_write_w(rv, addr, data); + + rv->PC += rv->inst_len; + return true; +} + +// CL-type +static bool c_op_lw(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.lw"); + + uint16_t temp = 0; + temp |= (inst & 0b0000000001000000) >> 4; + temp |= (inst & FC_IMM_12_10) >> 7; + temp |= (inst & 0b0000000000100000) << 1; + + const uint16_t imm = temp; + const uint16_t rd = c_dec_rdc(inst) | 0x08; + const uint16_t rs1 = c_dec_rs1c(inst) | 0x08; + const uint32_t addr = rv->X[rs1] + imm; + + if(addr & 3){ + rv_except_load_misaligned(rv, addr); + return false; + } + rv->X[rd] = rv->io.mem_read_w(rv, addr); + rv->PC += rv->inst_len; return true; } @@ -992,34 +1013,47 @@ static bool c_op_fswsp(struct riscv_t *rv, uint16_t inst) rv->PC += rv->inst_len; return true; } + +static bool c_op_fld(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} + +static bool c_op_flw(struct riscv_t *rv, uint16_t inst) +{ + rv->PC += rv->inst_len; + return true; +} #else #define c_op_fldsp NULL #define c_op_flwsp NULL #define c_op_fswsp NULL #define c_op_fsdsp NULL +#define c_op_fld NULL +#define c_op_flw NULL #endif // ENABLE_RV32F #endif // ENABLE_RV32C /* TODO: function implemetation */ -// #define c_op_addi4spn NULL - done / tested -// #define c_op_addi NULL - done / tested -// #define c_op_swsp NULL - done / tested -// #define c_op_li NULL - done / tested -// #define c_op_slli NULL -// #define c_op_fld NULL -// #define c_op_jal NULL -// #define c_op_lw NULL -// #define c_op_lwsp NULL -// #define c_op_flw NULL -// #define c_op_lui NULL -// #define c_op_misc_alu NULL -// #define c_op_jalr NULL -// #define c_op_fsd NULL -// #define c_op_j NULL -// #define c_op_beqz NULL -// #define c_op_fsw NULL -// #define c_op_bnez NULL +// c_op_addi4spn - done / tested +// c_op_addi - done / tested +// c_op_swsp - done / tested +// c_op_li - done / tested +// c_op_slli NULL +// c_op_jal NULL +// c_op_lw NULL - done / not tested +// c_op_lwsp NULL - done / not tested +// c_op_lui NULL +// c_op_misc_alu NULL +// c_op_jalr NULL +// c_op_fsd NULL +// c_op_j NULL +// c_op_beqz NULL +// c_op_fsw NULL +// c_op_bnez NULL +// c_op_sw // opcode handler type typedef bool (*opcode_t)(struct riscv_t *rv, uint32_t inst); From bc04ca481991c87c788d9e4cc98fe5a5b5753c80 Mon Sep 17 00:00:00 2001 From: Uduru Date: Wed, 6 Jan 2021 08:35:07 +0800 Subject: [PATCH 07/29] Inplemented CJ-type instructions. In `riscv.c`: - Inplemented `c_op_j()` , `c_op_jal()` --- riscv.c | 77 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/riscv.c b/riscv.c index 101cfec5..95812d5f 100644 --- a/riscv.c +++ b/riscv.c @@ -859,12 +859,6 @@ static bool c_op_fsw(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_jal(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - static bool c_op_li(struct riscv_t *rv, uint16_t inst) { debug_print("Entered c.li"); @@ -890,12 +884,6 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_j(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) { rv->PC += rv->inst_len; @@ -989,6 +977,53 @@ static bool c_op_lw(struct riscv_t *rv, uint16_t inst) return true; } +// CJ-type +static bool c_op_j(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.j"); + + uint32_t temp = 0; + // ....xxxx....xxxx + temp |= (inst & 0b0000000000111000) >> 2; + temp |= (inst & 0b0000100000000000) >> 7; + temp |= (inst & 0b0000000000000100) << 3; + temp |= (inst & 0b0000000010000000) >> 1; + temp |= (inst & 0b0000000001000000) << 1; + temp |= (inst & 0b0000011000000000) >> 1; + temp |= (inst & 0b0000000100000000) << 2; + temp |= (inst & 0b0001000000000000) >> 1; + + const uint32_t imm = sign_extend_h(temp); + + rv->PC += imm; + return true; +} + +static bool c_op_jal(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.jal"); + + uint32_t temp = 0; + // ....xxxx....xxxx + temp |= (inst & 0b0000000000111000) >> 2; + temp |= (inst & 0b0000100000000000) >> 7; + temp |= (inst & 0b0000000000000100) << 3; + temp |= (inst & 0b0000000010000000) >> 1; + temp |= (inst & 0b0000000001000000) << 1; + temp |= (inst & 0b0000011000000000) >> 1; + temp |= (inst & 0b0000000100000000) << 2; + temp |= (inst & 0b0001000000000000) >> 1; + + const uint32_t imm = sign_extend_h(temp); + + rv->X[1] = rv->PC + 2; + rv->PC += imm; + + return true; +} + +// CR-type + #ifdef ENABLE_RV32F static bool c_op_fldsp(struct riscv_t *rv, uint16_t inst) { @@ -1036,20 +1071,20 @@ static bool c_op_flw(struct riscv_t *rv, uint16_t inst) #endif // ENABLE_RV32C -/* TODO: function implemetation */ -// c_op_addi4spn - done / tested -// c_op_addi - done / tested -// c_op_swsp - done / tested -// c_op_li - done / tested +/* TODO: function implemetation and Test Correctness*/ +// c_op_addi4spn - done +// c_op_addi - done +// c_op_swsp - done +// c_op_li - done // c_op_slli NULL -// c_op_jal NULL -// c_op_lw NULL - done / not tested -// c_op_lwsp NULL - done / not tested +// c_op_jal - done +// c_op_lw - done +// c_op_lwsp - done // c_op_lui NULL // c_op_misc_alu NULL // c_op_jalr NULL // c_op_fsd NULL -// c_op_j NULL +// c_op_j - done // c_op_beqz NULL // c_op_fsw NULL // c_op_bnez NULL From 147da156e543350f484f5bed1b54d4201247b434 Mon Sep 17 00:00:00 2001 From: Uduru Date: Thu, 7 Jan 2021 04:49:44 +0800 Subject: [PATCH 08/29] Modified target degug to make sure rebuild --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b6e736c1..5f6e39d0 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ clean: distclean: clean $(RM) $(OUT)/DOOM1.WAD $(OUT)/DOOM1.WAD.sha1 -debug: debug_setting +debug: clean debug_setting debug_setting: CFLAGS += -D DEBUG debug_setting: all From 59077320c1592b7a9ede8154242ebd4d865f37b7 Mon Sep 17 00:00:00 2001 From: Uduru Date: Thu, 7 Jan 2021 07:12:43 +0800 Subject: [PATCH 09/29] Implemented CJ-type inst. In `riscv.c` - Added `c_op_cjtype()` - Added instruction unaligned exception check for PC modifying instructions In `riscv_private.h`: - Removed unneeded masks TODO: - Find out rules for instruction functions' (op_XXX) return value --- riscv.c | 35 +++++++++++++++++++++++++++-------- riscv_private.h | 1 - 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/riscv.c b/riscv.c index 95812d5f..61b10bcb 100644 --- a/riscv.c +++ b/riscv.c @@ -902,12 +902,6 @@ static bool c_op_slli(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_jalr(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - // CI-type static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) { @@ -1023,6 +1017,32 @@ static bool c_op_jal(struct riscv_t *rv, uint16_t inst) } // CR-type +static bool c_op_cr(struct riscv_t *rv, uint16_t inst) +{ + const rs1 = c_dec_rs1(inst); + + switch((inst & 0x1000) >> 12){ + case 0: // c.jr + debug_print("Entered c.jr"); + rv->PC = rv->X[rs1]; + break; + case 1: // c.jalr + debug_print("Entered c.jalr"); + rv->X[1] = rv->PC + 2; + rv->PC = rv->X[rs1]; + break; + default: + assert(!"Should be unreachbale."); + break; + } + + if(rv->PC & 1){ + rv_except_inst_misaligned(rv, rv->PC); + return false; + } + + return true; +} #ifdef ENABLE_RV32F static bool c_op_fldsp(struct riscv_t *rv, uint16_t inst) @@ -1111,7 +1131,7 @@ static const c_opcode_t c_opcodes[] = { c_op_fld, c_op_jal, c_op_fldsp, NULL, // 001 c_op_lw, c_op_li, c_op_lwsp, NULL, // 010 c_op_flw, c_op_lui, c_op_flwsp, NULL, // 011 - NULL, c_op_misc_alu, c_op_jalr, NULL, // 100 + NULL, c_op_misc_alu, c_op_cr, NULL, // 100 c_op_fsd, c_op_j, c_op_fsdsp, NULL, // 101 c_op_sw, c_op_beqz, c_op_swsp, NULL, // 110 c_op_fsw, c_op_bnez, c_op_fswsp, NULL, // 111 @@ -1151,7 +1171,6 @@ void rv_step(struct riscv_t *rv, int32_t cycles) // DEBUG: Print accepted c-instruction debug_print_val(c_index); debug_print_val(inst); - // printf("c_index: %d, inst: %x\n", c_index, inst); assert(op); rv->inst_len = INST_16; if (!op(rv, inst)) diff --git a/riscv_private.h b/riscv_private.h index 03d1d130..4f98f066 100644 --- a/riscv_private.h +++ b/riscv_private.h @@ -79,7 +79,6 @@ enum { // ....xxxx....xxxx....xxxx....xxxx FC_OPCODE = 0b00000000000000000000000000000011, // compressed-instuction FC_FUNC3 = 0b00000000000000001110000000000000, - FCR_FUNCT4 = 0b00000000000000001111000000000000, // ....xxxx....xxxx....xxxx....xxxx FC_RS1C = 0b00000000000000000000001110000000, FC_RS2C = 0b00000000000000000000000000011100, From 5c8b4a75b8a04429aa30318cd767a5bac7145ad3 Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Thu, 7 Jan 2021 13:54:23 +0800 Subject: [PATCH 10/29] Revise Debug Function In riscv.c: - Modify print_register() to being a macro --- riscv.c | 63 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/riscv.c b/riscv.c index 61b10bcb..0eb72d32 100644 --- a/riscv.c +++ b/riscv.c @@ -8,23 +8,23 @@ #include "riscv_private.h" #ifdef DEBUG -#define print_register(rv) __print_register((rv)) -inline static void __print_register(struct riscv_t *rv) -{ - for (int i = 0; i < 32; ++i) { - printf("X[%02d] = %08X\t", i, rv->X[i]); - if(!(i % 5)){ - putchar('\n'); - } - } - putchar('\n'); -} +#define print_register(rv) \ + do { \ + for (int i = 0; i < 32; ++i) { \ + printf("X[%02d] = %08X\t", i, rv->X[i]); \ + if (!(i % 5)) { \ + putchar('\n'); \ + } \ + } \ + putchar('\n'); \ + } while (0) + #define debug_print(str) printf("DEBUG: " #str "\n") -#define debug_print_val(var) printf("DEBUG: " #var " = %08X(hex)\n", var) +#define debug_print_hexval(var) printf("DEBUG: " #var " = %08X(hex)\n", var) #else -#define print_register(rv) (void)0 -#define debug_print(str) (void)0 -#define debug_print_val(var) (void)0 +#define print_register(rv) (void) 0 +#define debug_print(str) (void) 0 +#define debug_print_hexval(var) (void) 0 #endif static void rv_except_inst_misaligned(struct riscv_t *rv, uint32_t old_pc) @@ -906,7 +906,7 @@ static bool c_op_slli(struct riscv_t *rv, uint16_t inst) static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) { debug_print("Entered c.lwsp"); - + uint16_t temp = 0; temp |= ((inst & FCI_IMM_6_2) | 0b1110000) >> 2; temp |= (inst & FCI_IMM_12) >> 7; @@ -916,7 +916,7 @@ static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) const uint16_t rd = c_dec_rd(inst); const uint16_t addr = rv->X[2] + imm; - if(addr & 3){ + if (addr & 3) { rv_except_load_misaligned(rv, addr); return false; } @@ -948,7 +948,7 @@ static bool c_op_swsp(struct riscv_t *rv, uint16_t inst) // CL-type static bool c_op_lw(struct riscv_t *rv, uint16_t inst) -{ +{ debug_print("Entered c.lw"); uint16_t temp = 0; @@ -960,8 +960,8 @@ static bool c_op_lw(struct riscv_t *rv, uint16_t inst) const uint16_t rd = c_dec_rdc(inst) | 0x08; const uint16_t rs1 = c_dec_rs1c(inst) | 0x08; const uint32_t addr = rv->X[rs1] + imm; - - if(addr & 3){ + + if (addr & 3) { rv_except_load_misaligned(rv, addr); return false; } @@ -986,7 +986,7 @@ static bool c_op_j(struct riscv_t *rv, uint16_t inst) temp |= (inst & 0b0000011000000000) >> 1; temp |= (inst & 0b0000000100000000) << 2; temp |= (inst & 0b0001000000000000) >> 1; - + const uint32_t imm = sign_extend_h(temp); rv->PC += imm; @@ -1021,12 +1021,12 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) { const rs1 = c_dec_rs1(inst); - switch((inst & 0x1000) >> 12){ - case 0: // c.jr + switch ((inst & 0x1000) >> 12) { + case 0: // c.jr debug_print("Entered c.jr"); rv->PC = rv->X[rs1]; break; - case 1: // c.jalr + case 1: // c.jalr debug_print("Entered c.jalr"); rv->X[1] = rv->PC + 2; rv->PC = rv->X[rs1]; @@ -1036,7 +1036,7 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) break; } - if(rv->PC & 1){ + if (rv->PC & 1) { rv_except_inst_misaligned(rv, rv->PC); return false; } @@ -1044,6 +1044,7 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) return true; } +/* No RV32C.F support */ #ifdef ENABLE_RV32F static bool c_op_fldsp(struct riscv_t *rv, uint16_t inst) { @@ -1092,13 +1093,13 @@ static bool c_op_flw(struct riscv_t *rv, uint16_t inst) /* TODO: function implemetation and Test Correctness*/ -// c_op_addi4spn - done +// c_op_addi4spn - done // c_op_addi - done // c_op_swsp - done // c_op_li - done -// c_op_slli NULL +// c_op_slli NULL // c_op_jal - done -// c_op_lw - done +// c_op_lw - done // c_op_lwsp - done // c_op_lui NULL // c_op_misc_alu NULL @@ -1108,7 +1109,7 @@ static bool c_op_flw(struct riscv_t *rv, uint16_t inst) // c_op_beqz NULL // c_op_fsw NULL // c_op_bnez NULL -// c_op_sw +// c_op_sw // opcode handler type typedef bool (*opcode_t)(struct riscv_t *rv, uint32_t inst); @@ -1169,8 +1170,8 @@ void rv_step(struct riscv_t *rv, int32_t cycles) const c_opcode_t op = c_opcodes[c_index]; // DEBUG: Print accepted c-instruction - debug_print_val(c_index); - debug_print_val(inst); + debug_print_hexval(c_index); + debug_print_hexval(inst); assert(op); rv->inst_len = INST_16; if (!op(rv, inst)) From 00bc59ca472e52eb00a178f3a7a25d128b12d851 Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Thu, 7 Jan 2021 14:02:49 +0800 Subject: [PATCH 11/29] Add Define NULL in Compressed Inst. In risc.c: - Add compressed instruction define NULL --- riscv.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/riscv.c b/riscv.c index 0eb72d32..52396141 100644 --- a/riscv.c +++ b/riscv.c @@ -1089,6 +1089,24 @@ static bool c_op_flw(struct riscv_t *rv, uint16_t inst) #define c_op_fld NULL #define c_op_flw NULL #endif // ENABLE_RV32F +#else +#define c_op_addi4spn NULL +#define c_op_addi NULL +#define c_op_swsp NULL +#define c_op_li NULL +#define c_op_slli NULL +#define c_op_jal NULL +#define c_op_lw NULL +#define c_op_lwsp NULL +#define c_op_lui NULL +#define c_op_misc_alu NULL +#define c_op_jalr NULL +#define c_op_fsd NULL +#define c_op_j NULL +#define c_op_beqz NULL +#define c_op_fsw NULL +#define c_op_bnez NULL +#define c_op_sw NULL #endif // ENABLE_RV32C From 8a505f049738f9cac93e4d8978e64da851163258 Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Thu, 7 Jan 2021 15:17:54 +0800 Subject: [PATCH 12/29] Revise Compressed Float Inst. Definition In riscv.c: - Extract RV32C.F from RV32C block --- riscv.c | 69 ++++++++++++++++++--------------------------------------- 1 file changed, 22 insertions(+), 47 deletions(-) diff --git a/riscv.c b/riscv.c index 52396141..4593a949 100644 --- a/riscv.c +++ b/riscv.c @@ -794,7 +794,7 @@ static bool op_amo(struct riscv_t *rv, uint32_t inst) #ifdef ENABLE_RV32C static bool c_op_addi(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.addi"); + debug_print("Entered c.addi/nop"); uint16_t tmp = (uint16_t)(((inst & FCI_IMM_12) >> 5) | (inst & FCI_IMM_6_2)) >> 2; @@ -874,6 +874,20 @@ static bool c_op_li(struct riscv_t *rv, uint16_t inst) static bool c_op_lui(struct riscv_t *rv, uint16_t inst) { + debug_print("Entered c.lui/addi16sp"); + const uint16_t rd = c_dec_rd(inst); + /* TODO */ + if (rd == 2) { + // C.ADDI16SP + + } else if (rd != 0) { + // C.LUI + + } else { + assert(!"Should be unreachbale."); + } + + rv->PC += rv->inst_len; return true; } @@ -1043,52 +1057,6 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) return true; } - -/* No RV32C.F support */ -#ifdef ENABLE_RV32F -static bool c_op_fldsp(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_flwsp(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_fsdsp(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_fswsp(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_fld(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_flw(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} -#else -#define c_op_fldsp NULL -#define c_op_flwsp NULL -#define c_op_fswsp NULL -#define c_op_fsdsp NULL -#define c_op_fld NULL -#define c_op_flw NULL -#endif // ENABLE_RV32F #else #define c_op_addi4spn NULL #define c_op_addi NULL @@ -1109,6 +1077,13 @@ static bool c_op_flw(struct riscv_t *rv, uint16_t inst) #define c_op_sw NULL #endif // ENABLE_RV32C +/* No RV32C.F support */ +#define c_op_fldsp NULL +#define c_op_flwsp NULL +#define c_op_fswsp NULL +#define c_op_fsdsp NULL +#define c_op_fld NULL +#define c_op_flw NULL /* TODO: function implemetation and Test Correctness*/ // c_op_addi4spn - done From 505e13975cc7aa144916af263d8e5670d197a0c1 Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Thu, 7 Jan 2021 16:07:29 +0800 Subject: [PATCH 13/29] Implement C.LUI & C.ADDI16SP Inst. In riscv.c: - Implement c_op_lui function - Revise a few sign-extended immediates --- riscv.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/riscv.c b/riscv.c index 4593a949..afbe9808 100644 --- a/riscv.c +++ b/riscv.c @@ -798,7 +798,7 @@ static bool c_op_addi(struct riscv_t *rv, uint16_t inst) uint16_t tmp = (uint16_t)(((inst & FCI_IMM_12) >> 5) | (inst & FCI_IMM_6_2)) >> 2; - const int16_t imm = (0x20 & tmp) ? 0xffc0 | tmp : tmp; + const int32_t imm = (0x20 & tmp) ? 0xffffffc0 | tmp : tmp; const uint16_t rd = c_dec_rd(inst); // dispatch operation type @@ -864,7 +864,7 @@ static bool c_op_li(struct riscv_t *rv, uint16_t inst) debug_print("Entered c.li"); uint16_t tmp = (uint16_t)((inst & 0x1000) >> 7 | (inst & 0x7c) >> 2); - const int16_t imm = (0x20 & tmp) ? 0xffc0 | tmp : tmp; + const int32_t imm = (tmp & 0x20) ? 0xffffffc0 | tmp : tmp; const uint16_t rd = c_dec_rd(inst); rv->X[rd] = imm; @@ -879,15 +879,26 @@ static bool c_op_lui(struct riscv_t *rv, uint16_t inst) /* TODO */ if (rd == 2) { // C.ADDI16SP - + uint32_t tmp = (inst & 0x1000) >> 3; + tmp |= (inst & 0x40); + tmp |= (inst & 0x20) << 1; + tmp |= (inst & 0x18) << 4; + tmp |= (inst & 0x4) << 3; + const int32_t imm = (tmp & 0x200) ? 0xfffffc | tmp : tmp; + if (imm == 0) + assert(!"Should not be zero."); + rv->X[rd] += imm; } else if (rd != 0) { // C.LUI - + uint32_t tmp = (inst & 0x1000) << 5 | (inst & 0x7c) << 12; + const int32_t imm = (tmp & 0x20000) ? 0xfffc0000 | tmp : tmp; + if (imm == 0) + assert(!"Should not be zero."); + rv->X[rd] = imm; } else { assert(!"Should be unreachbale."); } - rv->PC += rv->inst_len; return true; } From 5b3491ed455b2383d4bbc3935fc0401baa5ecc79 Mon Sep 17 00:00:00 2001 From: Uduru Date: Fri, 8 Jan 2021 16:18:30 +0800 Subject: [PATCH 14/29] Implemented CB-type Inst, Fixed Few Sign-Extension Bugs in `riscv.c`: - Implemented c_bneq(), c_beqz() - Fixed overlooked sign extension bugs in `riscv-private.c`: - Added c_dec_cbtype_imm(), c_dec_cjtype_imm() --- riscv.c | 77 ++++++++++++++++++++++++------------------------- riscv_private.h | 34 ++++++++++++++++++++++ 2 files changed, 72 insertions(+), 39 deletions(-) diff --git a/riscv.c b/riscv.c index afbe9808..37e0238a 100644 --- a/riscv.c +++ b/riscv.c @@ -909,18 +909,6 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - static bool c_op_slli(struct riscv_t *rv, uint16_t inst) { rv->PC += rv->inst_len; @@ -1001,19 +989,7 @@ static bool c_op_j(struct riscv_t *rv, uint16_t inst) { debug_print("Entered c.j"); - uint32_t temp = 0; - // ....xxxx....xxxx - temp |= (inst & 0b0000000000111000) >> 2; - temp |= (inst & 0b0000100000000000) >> 7; - temp |= (inst & 0b0000000000000100) << 3; - temp |= (inst & 0b0000000010000000) >> 1; - temp |= (inst & 0b0000000001000000) << 1; - temp |= (inst & 0b0000011000000000) >> 1; - temp |= (inst & 0b0000000100000000) << 2; - temp |= (inst & 0b0001000000000000) >> 1; - - const uint32_t imm = sign_extend_h(temp); - + const uint32_t imm = sign_extend_h(c_dec_cjtype_imm(inst)); rv->PC += imm; return true; } @@ -1022,22 +998,9 @@ static bool c_op_jal(struct riscv_t *rv, uint16_t inst) { debug_print("Entered c.jal"); - uint32_t temp = 0; - // ....xxxx....xxxx - temp |= (inst & 0b0000000000111000) >> 2; - temp |= (inst & 0b0000100000000000) >> 7; - temp |= (inst & 0b0000000000000100) << 3; - temp |= (inst & 0b0000000010000000) >> 1; - temp |= (inst & 0b0000000001000000) << 1; - temp |= (inst & 0b0000011000000000) >> 1; - temp |= (inst & 0b0000000100000000) << 2; - temp |= (inst & 0b0001000000000000) >> 1; - - const uint32_t imm = sign_extend_h(temp); - + const uint32_t imm = sign_extend_h(c_dec_cjtype_imm(inst)); rv->X[1] = rv->PC + 2; rv->PC += imm; - return true; } @@ -1068,6 +1031,41 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) return true; } + +// CB-type +static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.beqz"); + + const uint32_t imm = sign_extend_h(c_dec_cbtype_imm(inst)); + const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; + + if(!rv->X[rs1]){ + rv->PC += imm; + } + else{ + rv->PC += rv->inst_len; + } + + return true; +} + +static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.bnez"); + + const uint32_t imm = sign_extend_h(c_dec_cbtype_imm(inst)); + const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; + + if(rv->X[rs1]){ + rv->PC += imm; + } + else{ + rv->PC += rv->inst_len; + } + + return true; +} #else #define c_op_addi4spn NULL #define c_op_addi NULL @@ -1174,6 +1172,7 @@ void rv_step(struct riscv_t *rv, int32_t cycles) const c_opcode_t op = c_opcodes[c_index]; // DEBUG: Print accepted c-instruction + debug_print_hexval(rv->PC); debug_print_hexval(c_index); debug_print_hexval(inst); assert(op); diff --git a/riscv_private.h b/riscv_private.h index 4f98f066..25429492 100644 --- a/riscv_private.h +++ b/riscv_private.h @@ -268,3 +268,37 @@ static inline uint16_t c_dec_rs2c(uint16_t x){ static inline uint16_t c_dec_rdc(uint16_t x){ return (uint16_t)((x & FC_RDC) >> 2U); } + +static inline uint16_t c_dec_cjtype_imm(uint16_t x){ + uint16_t temp = 0; + // ....xxxx....xxxx + temp |= (x & 0b0000000000111000) >> 2; + temp |= (x & 0b0000100000000000) >> 7; + temp |= (x & 0b0000000000000100) << 3; + temp |= (x & 0b0000000010000000) >> 1; + temp |= (x & 0b0000000001000000) << 1; + temp |= (x & 0b0000011000000000) >> 1; + temp |= (x & 0b0000000100000000) << 2; + temp |= (x & 0b0001000000000000) >> 1; + // extend to 16 bit + for(int i = 1; i < 4; ++i){ + temp |= (0x0800 & temp) << i; + } + + return temp; +} + +static inline uint16_t c_dec_cbtype_imm(uint16_t x){ + uint16_t temp = 0; + // ....xxxx....xxxx + temp |= (x & 0b0000000000011000) >> 2; + temp |= (x & 0b0000110000000000) >> 7; + temp |= (x & 0b0000000000000100) << 3; + temp |= (x & 0b0000000001100000) << 1; + temp |= (x & 0b0001000000000000) >> 4; + // extend to 16 bit + for(int i = 1; i < 8; ++i){ + temp |= (0x0100 & temp) << i; + } + return temp; +} \ No newline at end of file From 2ff89bb611822b12a685fa54c4379139c8c855b7 Mon Sep 17 00:00:00 2001 From: Uduru Date: Fri, 8 Jan 2021 16:42:07 +0800 Subject: [PATCH 15/29] Implemented c.sw Instruction In `riscv.c`: - Added c_op_sw(); --- riscv.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/riscv.c b/riscv.c index 37e0238a..4ead522e 100644 --- a/riscv.c +++ b/riscv.c @@ -817,19 +817,6 @@ static bool c_op_addi(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_sw(struct riscv_t *rv, uint16_t inst) -{ - // const uint16_t imm = - // (inst & FC_IMM_12_10) >> 7 | (inst & 0x20) >> 4 | (inst & 0x10) << 1; - // const uint16_t rs1 = c_dec_rs1c(inst); - // const uint16_t rs2 = c_dec_rs2c(inst); - // printf("%x, %x, %x\n", imm, rs1, rs2); - - - rv->PC += rv->inst_len; - return true; -} - static bool c_op_addi4spn(struct riscv_t *rv, uint16_t inst) { debug_print("Entered c.addi4spn"); @@ -984,6 +971,33 @@ static bool c_op_lw(struct riscv_t *rv, uint16_t inst) return true; } +// CS-type +static bool c_op_sw(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.sw"); + + uint32_t temp = 0; + // ....xxxx....xxxx + temp |= (inst & 0b0000000001000000) >> 4; + temp |= (inst & FC_IMM_12_10) >> 7; + temp |= (inst & 0b0000000000100000) << 1; + + const uint32_t imm = temp; + const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; + const uint32_t rs2 = c_dec_rs2c(inst) | 0x08; + const uint32_t addr = rv->X[rs1] + imm; + const uint32_t data = rv->X[rs2]; + + if (addr & 3) { + rv_except_store_misaligned(rv, addr); + return false; + } + rv->io.mem_write_w(rv, addr, data); + + rv->PC += rv->inst_len; + return true; +} + // CJ-type static bool c_op_j(struct riscv_t *rv, uint16_t inst) { @@ -1099,11 +1113,11 @@ static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) // c_op_addi - done // c_op_swsp - done // c_op_li - done -// c_op_slli NULL +// c_op_slli NULL // c_op_jal - done // c_op_lw - done // c_op_lwsp - done -// c_op_lui NULL +// c_op_lui - done // c_op_misc_alu NULL // c_op_jalr NULL // c_op_fsd NULL From ed15df6f276466436d0c21cd7a9fa32e34f24959 Mon Sep 17 00:00:00 2001 From: Uduru Date: Fri, 8 Jan 2021 23:12:17 +0800 Subject: [PATCH 16/29] Implemented c_op_slli() in `riscv.c`: - Added c_op_slli() --- riscv.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/riscv.c b/riscv.c index 4ead522e..9c96d3c6 100644 --- a/riscv.c +++ b/riscv.c @@ -834,18 +834,6 @@ static bool c_op_addi4spn(struct riscv_t *rv, uint16_t inst) return true; } -static bool c_op_fsd(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - -static bool c_op_fsw(struct riscv_t *rv, uint16_t inst) -{ - rv->PC += rv->inst_len; - return true; -} - static bool c_op_li(struct riscv_t *rv, uint16_t inst) { debug_print("Entered c.li"); @@ -898,6 +886,19 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) static bool c_op_slli(struct riscv_t *rv, uint16_t inst) { + debug_print("Entered c.slli"); + + uint32_t temp = 0; + temp |= (inst & FCI_IMM_12) >> 7; + temp |= (inst & FCI_IMM_6_2) >> 2; + + const uint32_t shamt = temp; + const uint32_t rd = c_dec_rd(inst); + + if(rd){ + rv->X[rd] <<= shamt; + } + rv->PC += rv->inst_len; return true; } @@ -1021,7 +1022,7 @@ static bool c_op_jal(struct riscv_t *rv, uint16_t inst) // CR-type static bool c_op_cr(struct riscv_t *rv, uint16_t inst) { - const rs1 = c_dec_rs1(inst); + const uint32_t rs1 = c_dec_rs1(inst); switch ((inst & 0x1000) >> 12) { case 0: // c.jr @@ -1092,10 +1093,8 @@ static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) #define c_op_lui NULL #define c_op_misc_alu NULL #define c_op_jalr NULL -#define c_op_fsd NULL #define c_op_j NULL #define c_op_beqz NULL -#define c_op_fsw NULL #define c_op_bnez NULL #define c_op_sw NULL #endif // ENABLE_RV32C @@ -1107,6 +1106,8 @@ static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) #define c_op_fsdsp NULL #define c_op_fld NULL #define c_op_flw NULL +#define c_op_fsw NULL +#define c_op_fsd NULL /* TODO: function implemetation and Test Correctness*/ // c_op_addi4spn - done @@ -1119,13 +1120,11 @@ static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) // c_op_lwsp - done // c_op_lui - done // c_op_misc_alu NULL -// c_op_jalr NULL -// c_op_fsd NULL +// c_op_jalr NULL - done // c_op_j - done -// c_op_beqz NULL -// c_op_fsw NULL -// c_op_bnez NULL -// c_op_sw +// c_op_beqz - done +// c_op_bnez - done +// c_op_sw - done // opcode handler type typedef bool (*opcode_t)(struct riscv_t *rv, uint32_t inst); From 9379eebe28aa1dd0c89c0ab789c2f566fc7f4230 Mon Sep 17 00:00:00 2001 From: Uduru Date: Sat, 9 Jan 2021 01:29:51 +0800 Subject: [PATCH 17/29] Implement c.srli, c.srai, c.slli c.andi Inst. In `riscv.c`: - Started implementing c_op_misc_alu() - Added c_op_slli() - Added c_op_srli() - Added c_op_srai() - Added c_op_andi() TODO: - Change name of c_op_cr to fit future modification (add C.MV and C.ADD, etc.) --- riscv.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/riscv.c b/riscv.c index 9c96d3c6..fbb83d7f 100644 --- a/riscv.c +++ b/riscv.c @@ -878,8 +878,100 @@ static bool c_op_lui(struct riscv_t *rv, uint16_t inst) return true; } +// static bool c_op_XX(struct riscv_t *rv, uint16_t inst) +static bool c_op_srli(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.srli"); + + uint32_t temp = 0; + temp |= (inst & 0x1000) >> 7; + temp |= (inst & 0x007C) >> 2; + + const uint32_t shamt = temp; + const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; + + if(shamt & 0x10){ + assert(!"shamt[5]=1 Reserved"); + return false; + } + + rv->X[rs1] >>= shamt; + + return true; +} + +static bool c_op_srai(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.srai"); + + uint32_t temp = 0; + temp |= (inst & 0x1000) >> 7; + temp |= (inst & 0x007C) >> 2; + + const uint32_t shamt = temp; + const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; + + if(shamt & 0x10){ + assert(!"shamt[5]=1 Reserved"); + return false; + } + + const uint32_t mask = 0x80000000 | rv->X[rs1]; + rv->X[rs1] >>= shamt; + + for(unsigned int i = 0; i < shamt; ++i){ + rv->X[rs1] |= mask >> i; + } + + return true; +} + +static bool c_op_andi(struct riscv_t *rv, uint16_t inst) +{ + debug_print("Entered c.andi"); + + const uint16_t mask = (0x1000 & inst) << 3; + + uint16_t temp = 0; + for(int i = 0; i < 10; ++i){ + temp |= (mask >> i); + } + temp |= (inst & 0x007C) >> 2; + + const uint32_t imm = sign_extend_h(temp); + const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; + + rv->X[rs1] &= imm; + + return true; +} + static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) { + bool exec_result; + + // Find actual instruction + switch((inst & 0x0C00) >> 10){ + case 0: // C.SRLI + exec_result = c_op_srli(rv, inst); + break; + case 1: // C.SRAI + exec_result = c_op_srai(rv, inst); + break; + case 2: // C.ANDI + exec_result = c_op_andi(rv, inst); + break; + case 3: // Arithmistic + break; + default: + assert(!"Should not be reachable"); + break; + } + + if(!exec_result){ + return false; + } + rv->PC += rv->inst_len; return true; } From 15573d496396fbdc18a28260f8c9ac9d3034d9f8 Mon Sep 17 00:00:00 2001 From: Uduru Date: Sat, 9 Jan 2021 01:35:44 +0800 Subject: [PATCH 18/29] Relocated some debug print --- riscv.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/riscv.c b/riscv.c index fbb83d7f..8fe4496e 100644 --- a/riscv.c +++ b/riscv.c @@ -794,8 +794,6 @@ static bool op_amo(struct riscv_t *rv, uint32_t inst) #ifdef ENABLE_RV32C static bool c_op_addi(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.addi/nop"); - uint16_t tmp = (uint16_t)(((inst & FCI_IMM_12) >> 5) | (inst & FCI_IMM_6_2)) >> 2; const int32_t imm = (0x20 & tmp) ? 0xffffffc0 | tmp : tmp; @@ -804,8 +802,10 @@ static bool c_op_addi(struct riscv_t *rv, uint16_t inst) // dispatch operation type if (rd != 0) { // C.ADDI + debug_print("Entered c.addi"); rv->X[rd] += imm; } else { + debug_print("Entered c.nop"); // C.NOP } @@ -849,11 +849,11 @@ static bool c_op_li(struct riscv_t *rv, uint16_t inst) static bool c_op_lui(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.lui/addi16sp"); const uint16_t rd = c_dec_rd(inst); /* TODO */ if (rd == 2) { // C.ADDI16SP + debug_print("Entered addi16sp"); uint32_t tmp = (inst & 0x1000) >> 3; tmp |= (inst & 0x40); tmp |= (inst & 0x20) << 1; @@ -865,6 +865,7 @@ static bool c_op_lui(struct riscv_t *rv, uint16_t inst) rv->X[rd] += imm; } else if (rd != 0) { // C.LUI + debug_print("Entered c.lui"); uint32_t tmp = (inst & 0x1000) << 5 | (inst & 0x7c) << 12; const int32_t imm = (tmp & 0x20000) ? 0xfffc0000 | tmp : tmp; if (imm == 0) @@ -878,7 +879,6 @@ static bool c_op_lui(struct riscv_t *rv, uint16_t inst) return true; } -// static bool c_op_XX(struct riscv_t *rv, uint16_t inst) static bool c_op_srli(struct riscv_t *rv, uint16_t inst) { debug_print("Entered c.srli"); @@ -946,6 +946,7 @@ static bool c_op_andi(struct riscv_t *rv, uint16_t inst) return true; } +// static bool c_op_XX(struct riscv_t *rv, uint16_t inst) static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) { bool exec_result; From c153524581cb81f1074e967cdb073b81889af21e Mon Sep 17 00:00:00 2001 From: Uduru Date: Sat, 9 Jan 2021 02:36:07 +0800 Subject: [PATCH 19/29] Implemented c.sub, c.and, c.xor, c.or Inst. --- riscv.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/riscv.c b/riscv.c index 8fe4496e..14518a11 100644 --- a/riscv.c +++ b/riscv.c @@ -962,7 +962,47 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) case 2: // C.ANDI exec_result = c_op_andi(rv, inst); break; - case 3: // Arithmistic + case 3:; // Arithmistic + uint32_t temp = 0; + temp |= (inst & 0x1000) >> 10; + temp |= (inst & 0x0060) >> 5; + + const uint32_t funct = temp; + const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; + const uint32_t rs2 = c_dec_rs2c(inst) | 0x08; + const uint32_t rd = rs1; + + switch(funct){ + case 0: // SUB + debug_print("Entered c.sub"); + rv->X[rd] = rv->X[rs1] - rv->X[rs2]; + break; + case 1: // XOR + debug_print("Entered c.xor"); + rv->X[rd] = rv->X[rs1] ^ rv->X[rs2]; + break; + case 2: // OR + debug_print("Entered c.or"); + rv->X[rd] = rv->X[rs1] | rv->X[rs2]; + break; + case 3: // AND + debug_print("Entered c.and"); + rv->X[rd] = rv->X[rs1] & rv->X[rs2]; + break; + case 4: + assert(!"RV32F instructions"); + break; + case 5: + assert(!"RV32F instructions"); + break; + case 6: + case 7: + assert(!"Instruction preserved"); + break; + default: + assert(!"Should not be reachable"); + break; + } break; default: assert(!"Should not be reachable"); From 51ed5e1bad0dfb6d2a1f99c176061172dd655381 Mon Sep 17 00:00:00 2001 From: Uduru Date: Sat, 9 Jan 2021 03:20:40 +0800 Subject: [PATCH 20/29] Implemented c.mv, c.add Inst. In `riscv.c`: - Revised c_op_cr() to fit all 5 instructions: + c.add + c.mv + c.jr + c.jalr + c.ebreak (Debug message only) - Changed return value to false wherever PC might jump --- riscv.c | 61 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/riscv.c b/riscv.c index 14518a11..563e4957 100644 --- a/riscv.c +++ b/riscv.c @@ -990,10 +990,10 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) rv->X[rd] = rv->X[rs1] & rv->X[rs2]; break; case 4: - assert(!"RV32F instructions"); + assert(!"RV64/128C instructions"); break; case 5: - assert(!"RV32F instructions"); + assert(!"RV64/128C instructions"); break; case 6: case 7: @@ -1139,7 +1139,7 @@ static bool c_op_j(struct riscv_t *rv, uint16_t inst) const uint32_t imm = sign_extend_h(c_dec_cjtype_imm(inst)); rv->PC += imm; - return true; + return false; } static bool c_op_jal(struct riscv_t *rv, uint16_t inst) @@ -1149,34 +1149,59 @@ static bool c_op_jal(struct riscv_t *rv, uint16_t inst) const uint32_t imm = sign_extend_h(c_dec_cjtype_imm(inst)); rv->X[1] = rv->PC + 2; rv->PC += imm; - return true; + return false; } // CR-type static bool c_op_cr(struct riscv_t *rv, uint16_t inst) { const uint32_t rs1 = c_dec_rs1(inst); + const uint32_t rs2 = c_dec_rs2(inst); + const uint32_t rd = rs1; switch ((inst & 0x1000) >> 12) { - case 0: // c.jr - debug_print("Entered c.jr"); - rv->PC = rv->X[rs1]; + case 0: + if(rs2){ + debug_print("Entered c.mv"); + rv->X[rd] = rv->X[rs2]; + rv->PC += rv->inst_len; + } + else{ + debug_print("Entered c.jr"); + rv->PC = rv->X[rs1]; + + return false; + } break; - case 1: // c.jalr - debug_print("Entered c.jalr"); - rv->X[1] = rv->PC + 2; - rv->PC = rv->X[rs1]; + case 1: + if(rs1){ + if(rs2){ + debug_print("Entered c.add"); + rv->X[rd] = rv->X[rs1] + rv->X[rs2]; + rv->PC += rv->inst_len; + } + else{ + debug_print("Entered c.jalr"); + rv->X[1] = rv->PC + 2; + rv->PC = rv->X[rs1]; + + if (rv->PC & 1) { + rv_except_inst_misaligned(rv, rv->PC); + return false; + } + + return false; + } + } + else{ + debug_print("Entered c.ebreak"); + } break; default: assert(!"Should be unreachbale."); break; } - if (rv->PC & 1) { - rv_except_inst_misaligned(rv, rv->PC); - return false; - } - return true; } @@ -1195,7 +1220,7 @@ static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) rv->PC += rv->inst_len; } - return true; + return false; } static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) @@ -1212,7 +1237,7 @@ static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) rv->PC += rv->inst_len; } - return true; + return false; } #else #define c_op_addi4spn NULL From 8e338d7ea48d0d330397ea1c56472cbac164194e Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Fri, 15 Jan 2021 18:06:10 +0800 Subject: [PATCH 21/29] Fix Inst. Ebreak Function In riscv.c: - Add the ebreak function --- riscv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/riscv.c b/riscv.c index 563e4957..40ab183a 100644 --- a/riscv.c +++ b/riscv.c @@ -1195,6 +1195,7 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) } else{ debug_print("Entered c.ebreak"); + rv->io.on_ebreak(rv); } break; default: From 36deb34a821c450a2074d66afb21a16fb8fa849b Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Fri, 15 Jan 2021 18:27:52 +0800 Subject: [PATCH 22/29] Remove Unuseful Comment In riscv.c: - remove unuseful comment --- riscv.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/riscv.c b/riscv.c index 40ab183a..ac93ca52 100644 --- a/riscv.c +++ b/riscv.c @@ -850,7 +850,6 @@ static bool c_op_li(struct riscv_t *rv, uint16_t inst) static bool c_op_lui(struct riscv_t *rv, uint16_t inst) { const uint16_t rd = c_dec_rd(inst); - /* TODO */ if (rd == 2) { // C.ADDI16SP debug_print("Entered addi16sp"); @@ -1268,23 +1267,6 @@ static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) #define c_op_fsw NULL #define c_op_fsd NULL -/* TODO: function implemetation and Test Correctness*/ -// c_op_addi4spn - done -// c_op_addi - done -// c_op_swsp - done -// c_op_li - done -// c_op_slli NULL -// c_op_jal - done -// c_op_lw - done -// c_op_lwsp - done -// c_op_lui - done -// c_op_misc_alu NULL -// c_op_jalr NULL - done -// c_op_j - done -// c_op_beqz - done -// c_op_bnez - done -// c_op_sw - done - // opcode handler type typedef bool (*opcode_t)(struct riscv_t *rv, uint32_t inst); typedef bool (*c_opcode_t)(struct riscv_t *rv, uint16_t inst); From 5640c17c703473e185a9b1495342c7ddc99bc440 Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Sat, 16 Jan 2021 20:01:58 +0800 Subject: [PATCH 23/29] Revise Coding Format Using clang-format to format the code. --- riscv.c | 71 +++++++++++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/riscv.c b/riscv.c index ac93ca52..fe98d133 100644 --- a/riscv.c +++ b/riscv.c @@ -885,11 +885,11 @@ static bool c_op_srli(struct riscv_t *rv, uint16_t inst) uint32_t temp = 0; temp |= (inst & 0x1000) >> 7; temp |= (inst & 0x007C) >> 2; - + const uint32_t shamt = temp; const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; - if(shamt & 0x10){ + if (shamt & 0x10) { assert(!"shamt[5]=1 Reserved"); return false; } @@ -906,19 +906,19 @@ static bool c_op_srai(struct riscv_t *rv, uint16_t inst) uint32_t temp = 0; temp |= (inst & 0x1000) >> 7; temp |= (inst & 0x007C) >> 2; - + const uint32_t shamt = temp; const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; - if(shamt & 0x10){ + if (shamt & 0x10) { assert(!"shamt[5]=1 Reserved"); return false; } const uint32_t mask = 0x80000000 | rv->X[rs1]; rv->X[rs1] >>= shamt; - - for(unsigned int i = 0; i < shamt; ++i){ + + for (unsigned int i = 0; i < shamt; ++i) { rv->X[rs1] |= mask >> i; } @@ -929,14 +929,14 @@ static bool c_op_andi(struct riscv_t *rv, uint16_t inst) { debug_print("Entered c.andi"); - const uint16_t mask = (0x1000 & inst) << 3; - + const uint16_t mask = (0x1000 & inst) << 3; + uint16_t temp = 0; - for(int i = 0; i < 10; ++i){ + for (int i = 0; i < 10; ++i) { temp |= (mask >> i); } temp |= (inst & 0x007C) >> 2; - + const uint32_t imm = sign_extend_h(temp); const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; @@ -951,17 +951,17 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) bool exec_result; // Find actual instruction - switch((inst & 0x0C00) >> 10){ - case 0: // C.SRLI + switch ((inst & 0x0C00) >> 10) { + case 0: // C.SRLI exec_result = c_op_srli(rv, inst); break; - case 1: // C.SRAI + case 1: // C.SRAI exec_result = c_op_srai(rv, inst); break; - case 2: // C.ANDI + case 2: // C.ANDI exec_result = c_op_andi(rv, inst); break; - case 3:; // Arithmistic + case 3:; // Arithmistic uint32_t temp = 0; temp |= (inst & 0x1000) >> 10; temp |= (inst & 0x0060) >> 5; @@ -971,20 +971,20 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) const uint32_t rs2 = c_dec_rs2c(inst) | 0x08; const uint32_t rd = rs1; - switch(funct){ - case 0: // SUB + switch (funct) { + case 0: // SUB debug_print("Entered c.sub"); rv->X[rd] = rv->X[rs1] - rv->X[rs2]; break; - case 1: // XOR + case 1: // XOR debug_print("Entered c.xor"); rv->X[rd] = rv->X[rs1] ^ rv->X[rs2]; break; - case 2: // OR + case 2: // OR debug_print("Entered c.or"); rv->X[rd] = rv->X[rs1] | rv->X[rs2]; break; - case 3: // AND + case 3: // AND debug_print("Entered c.and"); rv->X[rd] = rv->X[rs1] & rv->X[rs2]; break; @@ -1008,7 +1008,7 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) break; } - if(!exec_result){ + if (!exec_result) { return false; } @@ -1027,7 +1027,7 @@ static bool c_op_slli(struct riscv_t *rv, uint16_t inst) const uint32_t shamt = temp; const uint32_t rd = c_dec_rd(inst); - if(rd){ + if (rd) { rv->X[rd] <<= shamt; } @@ -1159,13 +1159,12 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) const uint32_t rd = rs1; switch ((inst & 0x1000) >> 12) { - case 0: - if(rs2){ + case 0: + if (rs2) { debug_print("Entered c.mv"); rv->X[rd] = rv->X[rs2]; rv->PC += rv->inst_len; - } - else{ + } else { debug_print("Entered c.jr"); rv->PC = rv->X[rs1]; @@ -1173,13 +1172,12 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) } break; case 1: - if(rs1){ - if(rs2){ + if (rs1) { + if (rs2) { debug_print("Entered c.add"); rv->X[rd] = rv->X[rs1] + rv->X[rs2]; rv->PC += rv->inst_len; - } - else{ + } else { debug_print("Entered c.jalr"); rv->X[1] = rv->PC + 2; rv->PC = rv->X[rs1]; @@ -1191,8 +1189,7 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) return false; } - } - else{ + } else { debug_print("Entered c.ebreak"); rv->io.on_ebreak(rv); } @@ -1213,10 +1210,9 @@ static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) const uint32_t imm = sign_extend_h(c_dec_cbtype_imm(inst)); const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; - if(!rv->X[rs1]){ + if (!rv->X[rs1]) { rv->PC += imm; - } - else{ + } else { rv->PC += rv->inst_len; } @@ -1230,10 +1226,9 @@ static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) const uint32_t imm = sign_extend_h(c_dec_cbtype_imm(inst)); const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; - if(rv->X[rs1]){ + if (rv->X[rs1]) { rv->PC += imm; - } - else{ + } else { rv->PC += rv->inst_len; } From 69ba1e1efb7d2d25b6416fe8d447b3c3becdc4ce Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Sat, 16 Jan 2021 20:10:32 +0800 Subject: [PATCH 24/29] Remove Useless Comment Remove useless comment in .gitignore. --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 779f479d..ed1dd16b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,5 @@ build/DOOM1.WAD* build/rv32emu *.o *.o.d - -# Added by Uduru0522 test/ .vscode \ No newline at end of file From 6da4329f0758a01d175eab9c5ee50a071d14f5f2 Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Tue, 19 Jan 2021 23:47:42 +0800 Subject: [PATCH 25/29] Revise Address Validation Adding a condition, if RV is enabled, the addr_io check will be changed into 1. --- io.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/io.c b/io.c index 88b5f29d..08ce30e3 100644 --- a/io.c +++ b/io.c @@ -70,7 +70,11 @@ uint32_t memory_read_str(memory_t *m, uint8_t *dst, uint32_t addr, uint32_t max) uint32_t memory_read_ifetch(memory_t *m, uint32_t addr) { const uint32_t addr_lo = addr & mask_lo; - assert((addr_lo & 1) == 0); + #ifdef ENABLE_RV32C + assert((addr_lo & 1) == 0); + #else + assert((addr_lo & 3) == 0); + #endif chunk_t *c = m->chunks[addr >> 16]; assert(c); From a0d65f33858ac32833b625802f871498a0029d34 Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Wed, 20 Jan 2021 00:05:52 +0800 Subject: [PATCH 26/29] Remove Debug Setting & Transfer to Other Branch The debug setting and dumping is transferred to 'debug' branch. --- Makefile | 4 ---- riscv.c | 67 -------------------------------------------------------- 2 files changed, 71 deletions(-) diff --git a/Makefile b/Makefile index 5f6e39d0..1a8d6f8f 100644 --- a/Makefile +++ b/Makefile @@ -69,8 +69,4 @@ clean: distclean: clean $(RM) $(OUT)/DOOM1.WAD $(OUT)/DOOM1.WAD.sha1 -debug: clean debug_setting -debug_setting: CFLAGS += -D DEBUG -debug_setting: all - -include $(deps) diff --git a/riscv.c b/riscv.c index fe98d133..092816d8 100644 --- a/riscv.c +++ b/riscv.c @@ -7,26 +7,6 @@ #include "riscv.h" #include "riscv_private.h" -#ifdef DEBUG -#define print_register(rv) \ - do { \ - for (int i = 0; i < 32; ++i) { \ - printf("X[%02d] = %08X\t", i, rv->X[i]); \ - if (!(i % 5)) { \ - putchar('\n'); \ - } \ - } \ - putchar('\n'); \ - } while (0) - -#define debug_print(str) printf("DEBUG: " #str "\n") -#define debug_print_hexval(var) printf("DEBUG: " #var " = %08X(hex)\n", var) -#else -#define print_register(rv) (void) 0 -#define debug_print(str) (void) 0 -#define debug_print_hexval(var) (void) 0 -#endif - static void rv_except_inst_misaligned(struct riscv_t *rv, uint32_t old_pc) { const uint32_t base = rv->csr_mtvec & ~0x3; @@ -802,10 +782,8 @@ static bool c_op_addi(struct riscv_t *rv, uint16_t inst) // dispatch operation type if (rd != 0) { // C.ADDI - debug_print("Entered c.addi"); rv->X[rd] += imm; } else { - debug_print("Entered c.nop"); // C.NOP } @@ -819,7 +797,6 @@ static bool c_op_addi(struct riscv_t *rv, uint16_t inst) static bool c_op_addi4spn(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.addi4spn"); uint16_t temp = 0; temp |= (inst & 0x1800) >> 7; temp |= (inst & 0x780) >> 1; @@ -836,8 +813,6 @@ static bool c_op_addi4spn(struct riscv_t *rv, uint16_t inst) static bool c_op_li(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.li"); - uint16_t tmp = (uint16_t)((inst & 0x1000) >> 7 | (inst & 0x7c) >> 2); const int32_t imm = (tmp & 0x20) ? 0xffffffc0 | tmp : tmp; const uint16_t rd = c_dec_rd(inst); @@ -852,7 +827,6 @@ static bool c_op_lui(struct riscv_t *rv, uint16_t inst) const uint16_t rd = c_dec_rd(inst); if (rd == 2) { // C.ADDI16SP - debug_print("Entered addi16sp"); uint32_t tmp = (inst & 0x1000) >> 3; tmp |= (inst & 0x40); tmp |= (inst & 0x20) << 1; @@ -864,7 +838,6 @@ static bool c_op_lui(struct riscv_t *rv, uint16_t inst) rv->X[rd] += imm; } else if (rd != 0) { // C.LUI - debug_print("Entered c.lui"); uint32_t tmp = (inst & 0x1000) << 5 | (inst & 0x7c) << 12; const int32_t imm = (tmp & 0x20000) ? 0xfffc0000 | tmp : tmp; if (imm == 0) @@ -880,8 +853,6 @@ static bool c_op_lui(struct riscv_t *rv, uint16_t inst) static bool c_op_srli(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.srli"); - uint32_t temp = 0; temp |= (inst & 0x1000) >> 7; temp |= (inst & 0x007C) >> 2; @@ -901,8 +872,6 @@ static bool c_op_srli(struct riscv_t *rv, uint16_t inst) static bool c_op_srai(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.srai"); - uint32_t temp = 0; temp |= (inst & 0x1000) >> 7; temp |= (inst & 0x007C) >> 2; @@ -927,8 +896,6 @@ static bool c_op_srai(struct riscv_t *rv, uint16_t inst) static bool c_op_andi(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.andi"); - const uint16_t mask = (0x1000 & inst) << 3; uint16_t temp = 0; @@ -973,19 +940,15 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) switch (funct) { case 0: // SUB - debug_print("Entered c.sub"); rv->X[rd] = rv->X[rs1] - rv->X[rs2]; break; case 1: // XOR - debug_print("Entered c.xor"); rv->X[rd] = rv->X[rs1] ^ rv->X[rs2]; break; case 2: // OR - debug_print("Entered c.or"); rv->X[rd] = rv->X[rs1] | rv->X[rs2]; break; case 3: // AND - debug_print("Entered c.and"); rv->X[rd] = rv->X[rs1] & rv->X[rs2]; break; case 4: @@ -1018,8 +981,6 @@ static bool c_op_misc_alu(struct riscv_t *rv, uint16_t inst) static bool c_op_slli(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.slli"); - uint32_t temp = 0; temp |= (inst & FCI_IMM_12) >> 7; temp |= (inst & FCI_IMM_6_2) >> 2; @@ -1038,8 +999,6 @@ static bool c_op_slli(struct riscv_t *rv, uint16_t inst) // CI-type static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.lwsp"); - uint16_t temp = 0; temp |= ((inst & FCI_IMM_6_2) | 0b1110000) >> 2; temp |= (inst & FCI_IMM_12) >> 7; @@ -1062,8 +1021,6 @@ static bool c_op_lwsp(struct riscv_t *rv, uint16_t inst) // CSS-type static bool c_op_swsp(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.swsp"); - const uint16_t imm = (inst & 0x1e00) >> 7 | (inst & 0x180) >> 1; const uint16_t rs2 = c_dec_rs2(inst); const uint32_t addr = rv->X[2] + imm; @@ -1082,8 +1039,6 @@ static bool c_op_swsp(struct riscv_t *rv, uint16_t inst) // CL-type static bool c_op_lw(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.lw"); - uint16_t temp = 0; temp |= (inst & 0b0000000001000000) >> 4; temp |= (inst & FC_IMM_12_10) >> 7; @@ -1107,8 +1062,6 @@ static bool c_op_lw(struct riscv_t *rv, uint16_t inst) // CS-type static bool c_op_sw(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.sw"); - uint32_t temp = 0; // ....xxxx....xxxx temp |= (inst & 0b0000000001000000) >> 4; @@ -1134,8 +1087,6 @@ static bool c_op_sw(struct riscv_t *rv, uint16_t inst) // CJ-type static bool c_op_j(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.j"); - const uint32_t imm = sign_extend_h(c_dec_cjtype_imm(inst)); rv->PC += imm; return false; @@ -1143,8 +1094,6 @@ static bool c_op_j(struct riscv_t *rv, uint16_t inst) static bool c_op_jal(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.jal"); - const uint32_t imm = sign_extend_h(c_dec_cjtype_imm(inst)); rv->X[1] = rv->PC + 2; rv->PC += imm; @@ -1161,11 +1110,9 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) switch ((inst & 0x1000) >> 12) { case 0: if (rs2) { - debug_print("Entered c.mv"); rv->X[rd] = rv->X[rs2]; rv->PC += rv->inst_len; } else { - debug_print("Entered c.jr"); rv->PC = rv->X[rs1]; return false; @@ -1174,11 +1121,9 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) case 1: if (rs1) { if (rs2) { - debug_print("Entered c.add"); rv->X[rd] = rv->X[rs1] + rv->X[rs2]; rv->PC += rv->inst_len; } else { - debug_print("Entered c.jalr"); rv->X[1] = rv->PC + 2; rv->PC = rv->X[rs1]; @@ -1190,7 +1135,6 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) return false; } } else { - debug_print("Entered c.ebreak"); rv->io.on_ebreak(rv); } break; @@ -1205,8 +1149,6 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) // CB-type static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.beqz"); - const uint32_t imm = sign_extend_h(c_dec_cbtype_imm(inst)); const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; @@ -1221,8 +1163,6 @@ static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) { - debug_print("Entered c.bnez"); - const uint32_t imm = sign_extend_h(c_dec_cbtype_imm(inst)); const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; @@ -1320,10 +1260,6 @@ void rv_step(struct riscv_t *rv, int32_t cycles) (inst & FC_FUNC3) >> 11 | (inst & FC_OPCODE); const c_opcode_t op = c_opcodes[c_index]; - // DEBUG: Print accepted c-instruction - debug_print_hexval(rv->PC); - debug_print_hexval(c_index); - debug_print_hexval(inst); assert(op); rv->inst_len = INST_16; if (!op(rv, inst)) @@ -1331,9 +1267,6 @@ void rv_step(struct riscv_t *rv, int32_t cycles) // increment the cycles csr rv->csr_cycle++; - - // DEBUG: print register state - print_register(rv); } } } From 228b6e35dd291e35500a0e449991171a00345f7f Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Wed, 20 Jan 2021 22:11:19 +0800 Subject: [PATCH 27/29] Revise Code Format Reactivate clang in riscv_private.h, make it can be formated by clang. --- riscv_private.h | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/riscv_private.h b/riscv_private.h index 25429492..38ace339 100644 --- a/riscv_private.h +++ b/riscv_private.h @@ -99,7 +99,7 @@ enum { FCJ_IMM = 0b00000000000000000001111111111100, // ....xxxx....xxxx....xxxx....xxxx }; -// clang-format off +// clang-format on struct riscv_t { bool halt; @@ -131,7 +131,7 @@ struct riscv_t { INST_UNKNOWN = 0, INST_16 = 0x02, INST_32 = 0x04, - }inst_len; + } inst_len; }; // decode rd field @@ -240,36 +240,43 @@ static inline uint32_t sign_extend_b(uint32_t x) } // decode rs1 field -static inline uint16_t c_dec_rs1(uint16_t x){ +static inline uint16_t c_dec_rs1(uint16_t x) +{ return (uint16_t)((x & FC_RS1) >> 7U); } // decode rs2 field -static inline uint16_t c_dec_rs2(uint16_t x){ +static inline uint16_t c_dec_rs2(uint16_t x) +{ return (uint16_t)((x & FC_RS2) >> 2U); } // decode rd field -static inline uint16_t c_dec_rd(uint16_t x){ +static inline uint16_t c_dec_rd(uint16_t x) +{ return (uint16_t)((x & FC_RD) >> 7U); } // decode rs1' field -static inline uint16_t c_dec_rs1c(uint16_t x){ +static inline uint16_t c_dec_rs1c(uint16_t x) +{ return (uint16_t)((x & FC_RS1C) >> 7U); } // decode rs2' field -static inline uint16_t c_dec_rs2c(uint16_t x){ +static inline uint16_t c_dec_rs2c(uint16_t x) +{ return (uint16_t)((x & FC_RS2C) >> 2U); } // decode rd' field -static inline uint16_t c_dec_rdc(uint16_t x){ +static inline uint16_t c_dec_rdc(uint16_t x) +{ return (uint16_t)((x & FC_RDC) >> 2U); } -static inline uint16_t c_dec_cjtype_imm(uint16_t x){ +static inline uint16_t c_dec_cjtype_imm(uint16_t x) +{ uint16_t temp = 0; // ....xxxx....xxxx temp |= (x & 0b0000000000111000) >> 2; @@ -281,14 +288,15 @@ static inline uint16_t c_dec_cjtype_imm(uint16_t x){ temp |= (x & 0b0000000100000000) << 2; temp |= (x & 0b0001000000000000) >> 1; // extend to 16 bit - for(int i = 1; i < 4; ++i){ + for (int i = 1; i < 4; ++i) { temp |= (0x0800 & temp) << i; } return temp; } -static inline uint16_t c_dec_cbtype_imm(uint16_t x){ +static inline uint16_t c_dec_cbtype_imm(uint16_t x) +{ uint16_t temp = 0; // ....xxxx....xxxx temp |= (x & 0b0000000000011000) >> 2; @@ -297,7 +305,7 @@ static inline uint16_t c_dec_cbtype_imm(uint16_t x){ temp |= (x & 0b0000000001100000) << 1; temp |= (x & 0b0001000000000000) >> 4; // extend to 16 bit - for(int i = 1; i < 8; ++i){ + for (int i = 1; i < 8; ++i) { temp |= (0x0100 & temp) << i; } return temp; From 76e7d928273ad1e0975ee4fac6260c7d4e39f92b Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Wed, 20 Jan 2021 22:18:16 +0800 Subject: [PATCH 28/29] Rename a Directory in .gitignore Rename test/ to tests/. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ed1dd16b..8ab3b24c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ build/DOOM1.WAD* build/rv32emu *.o *.o.d -test/ +tests/ .vscode \ No newline at end of file From 70fe23468f36e37e0c80d0f6d65478e5edb6b0dd Mon Sep 17 00:00:00 2001 From: ccs100203 Date: Wed, 20 Jan 2021 23:21:54 +0800 Subject: [PATCH 29/29] Compact the If Condition & Add Some Comments Rewrite c_op_beqz & c_op_bnez into a ternary operator. --- riscv.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/riscv.c b/riscv.c index 092816d8..bcfd7f2c 100644 --- a/riscv.c +++ b/riscv.c @@ -1089,6 +1089,7 @@ static bool c_op_j(struct riscv_t *rv, uint16_t inst) { const uint32_t imm = sign_extend_h(c_dec_cjtype_imm(inst)); rv->PC += imm; + // can branch return false; } @@ -1097,6 +1098,7 @@ static bool c_op_jal(struct riscv_t *rv, uint16_t inst) const uint32_t imm = sign_extend_h(c_dec_cjtype_imm(inst)); rv->X[1] = rv->PC + 2; rv->PC += imm; + // can branch return false; } @@ -1110,31 +1112,34 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) switch ((inst & 0x1000) >> 12) { case 0: if (rs2) { + // C.MV rv->X[rd] = rv->X[rs2]; rv->PC += rv->inst_len; } else { + // C.JR rv->PC = rv->X[rs1]; - return false; } break; case 1: if (rs1) { if (rs2) { + // C.ADD rv->X[rd] = rv->X[rs1] + rv->X[rs2]; rv->PC += rv->inst_len; } else { + // C.JALR rv->X[1] = rv->PC + 2; rv->PC = rv->X[rs1]; - if (rv->PC & 1) { rv_except_inst_misaligned(rv, rv->PC); return false; } - + // can branch return false; } } else { + // C.EBREAK rv->io.on_ebreak(rv); } break; @@ -1142,7 +1147,6 @@ static bool c_op_cr(struct riscv_t *rv, uint16_t inst) assert(!"Should be unreachbale."); break; } - return true; } @@ -1151,13 +1155,8 @@ static bool c_op_beqz(struct riscv_t *rv, uint16_t inst) { const uint32_t imm = sign_extend_h(c_dec_cbtype_imm(inst)); const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; - - if (!rv->X[rs1]) { - rv->PC += imm; - } else { - rv->PC += rv->inst_len; - } - + rv->PC += (!rv->X[rs1]) ? imm : rv->inst_len; + // can branch return false; } @@ -1165,13 +1164,8 @@ static bool c_op_bnez(struct riscv_t *rv, uint16_t inst) { const uint32_t imm = sign_extend_h(c_dec_cbtype_imm(inst)); const uint32_t rs1 = c_dec_rs1c(inst) | 0x08; - - if (rv->X[rs1]) { - rv->PC += imm; - } else { - rv->PC += rv->inst_len; - } - + rv->PC += (rv->X[rs1]) ? imm : rv->inst_len; + // can branch return false; } #else