From bdcb5b297f9919bdd1a1b6031a3b5c469e982d14 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 21 May 2015 00:21:46 -0700 Subject: [PATCH] New RV64C proposal --- riscv/decode.h | 59 +++++++++++++++++------------ riscv/encoding.h | 72 +++++++++++++++++++++++------------ riscv/insns/c_add.h | 7 +++- riscv/insns/c_add3.h | 2 + riscv/insns/c_addi.h | 7 +++- riscv/insns/c_addi4spn.h | 2 + riscv/insns/c_addiw.h | 3 +- riscv/insns/c_addw.h | 1 + riscv/insns/c_and3.h | 2 + riscv/insns/c_jal.h | 4 ++ riscv/insns/c_ld.h | 2 +- riscv/insns/c_ldsp.h | 1 + riscv/insns/c_li.h | 10 ++--- riscv/insns/c_lui.h | 9 ++++- riscv/insns/c_lw.h | 2 +- riscv/insns/c_lwsp.h | 1 + riscv/insns/c_mv.h | 3 +- riscv/insns/c_or3.h | 2 + riscv/insns/c_sdsp.h | 2 +- riscv/insns/c_slli.h | 5 +-- riscv/insns/c_slliw.h | 3 ++ riscv/insns/c_srai.h | 3 ++ riscv/insns/c_srli.h | 3 ++ riscv/insns/c_sub.h | 3 ++ riscv/insns/c_sub3.h | 2 + riscv/insns/c_swsp.h | 2 +- spike_main/disasm.cc | 82 ++++++++++++++++++++++++++++++---------- 27 files changed, 210 insertions(+), 84 deletions(-) create mode 100644 riscv/insns/c_add3.h create mode 100644 riscv/insns/c_addi4spn.h create mode 100644 riscv/insns/c_and3.h create mode 100644 riscv/insns/c_jal.h create mode 100644 riscv/insns/c_or3.h create mode 100644 riscv/insns/c_slliw.h create mode 100644 riscv/insns/c_srai.h create mode 100644 riscv/insns/c_srli.h create mode 100644 riscv/insns/c_sub.h create mode 100644 riscv/insns/c_sub3.h diff --git a/riscv/decode.h b/riscv/decode.h index 4d4c447..4f57656 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -22,6 +22,9 @@ typedef uint64_t freg_t; const int NXPR = 32; const int NFPR = 32; +#define X_RA 1 +#define X_SP 2 + #define FP_RD_NE 0 #define FP_RD_0 1 #define FP_RD_DN 2 @@ -72,18 +75,22 @@ public: uint64_t csr() { return x(20, 12); } int64_t rvc_imm() { return x(2, 5) + (xs(12, 1) << 5); } + int64_t rvc_addi4spn_imm() { return (x(6, 1) << 2) + (x(5, 1) << 3) + (x(11, 2) << 4) + (x(7, 4) << 6); } + int64_t rvc_addi16sp_imm() { return (x(6, 1) << 4) + (x(5, 1) << 5) + (x(2, 3) << 6) + (xs(12, 1) << 9); } int64_t rvc_lwsp_imm() { return (x(4, 3) << 2) + (x(12, 1) << 5) + (x(2, 2) << 6); } int64_t rvc_ldsp_imm() { return (x(5, 2) << 3) + (x(12, 1) << 5) + (x(2, 3) << 6); } - int64_t rvc_lw_imm() { return (x(5, 2) << 3) + (x(10, 1) << 6) + (x(11, 1) << 2) + (x(12, 1) << 5); } - int64_t rvc_ld_imm() { return (x(5, 2) << 3) + (x(10, 1) << 6) + (x(11, 1) << 7) + (x(12, 1) << 5); } - int64_t rvc_j_imm() { return (xs(2, 3) << 9) + (x(5, 2) << 3) + (x(7, 1) << 1) + (x(8, 2) << 7) + (x(10, 1) << 6) + (x(11, 1) << 2) + (x(12, 1) << 5); } - int64_t rvc_b_imm() { return (x(5, 2) << 3) + (x(7, 1) << 1) + (xs(8, 2) << 7) + (x(10, 1) << 6) + (x(11, 1) << 2) + (x(12, 1) << 5); } + int64_t rvc_swsp_imm() { return (x(9, 4) << 2) + (x(7, 2) << 6); } + int64_t rvc_sdsp_imm() { return (x(10, 3) << 3) + (x(7, 3) << 6); } + int64_t rvc_lw_imm() { return (x(6, 1) << 2) + (x(10, 3) << 3) + (x(5, 1) << 6); } + int64_t rvc_ld_imm() { return (x(10, 3) << 3) + (x(5, 2) << 6); } + int64_t rvc_j_imm() { return (x(3, 4) << 1) + (x(2, 1) << 5) + (xs(7, 6) << 6); } + int64_t rvc_b_imm() { return (x(3, 4) << 1) + (x(2, 1) << 5) + (xs(10, 3) << 6); } uint64_t rvc_rd() { return rd(); } - uint64_t rvc_rs1() { return x(2, 5); } - uint64_t rvc_rs2() { return rd(); } - uint64_t rvc_rds() { return 8 + x(7, 3); } - uint64_t rvc_rs1s() { return 8 + x(2, 3); } - uint64_t rvc_rs2s() { return rvc_rds(); } + uint64_t rvc_rs1() { return rd(); } + uint64_t rvc_rs2() { return x(2, 5); } + uint64_t rvc_rds() { return 8 + x(10, 3); } + uint64_t rvc_rs1s() { return 8 + x(7, 3); } + uint64_t rvc_rs2s() { return 8 + x(2, 3); } private: insn_bits_t b; uint64_t x(int lo, int len) { return (b >> lo) & ((insn_bits_t(1) << len)-1); } @@ -111,27 +118,30 @@ private: // helpful macros, etc #define MMU (*p->get_mmu()) #define STATE (*p->get_state()) -#define RS1 STATE.XPR[insn.rs1()] -#define RS2 STATE.XPR[insn.rs2()] +#define READ_REG(reg) STATE.XPR[reg] +#define RS1 READ_REG(insn.rs1()) +#define RS2 READ_REG(insn.rs2()) #define WRITE_REG(reg, value) STATE.XPR.write(reg, value) #define WRITE_RD(value) WRITE_REG(insn.rd(), value) #ifdef RISCV_ENABLE_COMMITLOG #undef WRITE_REG #define WRITE_REG(reg, value) ({ \ - reg_t wdata = value; /* value is a func with side-effects */ \ - STATE.log_reg_write = (commit_log_reg_t){reg << 1, wdata}; \ + reg_t wdata = (value); /* value is a func with side-effects */ \ + STATE.log_reg_write = (commit_log_reg_t){(reg) << 1, wdata}; \ STATE.XPR.write(reg, wdata); \ }) #endif // RVC macros #define WRITE_RVC_RDS(value) WRITE_REG(insn.rvc_rds(), value) -#define RVC_RS1 STATE.XPR[insn.rvc_rs1()] -#define RVC_RS2 STATE.XPR[insn.rvc_rs2()] -#define RVC_RS1S STATE.XPR[insn.rvc_rs1s()] -#define RVC_RS2S STATE.XPR[insn.rvc_rs2s()] -#define RVC_SP STATE.XPR[2] +#define WRITE_RVC_RS1S(value) WRITE_REG(insn.rvc_rs1s(), value) +#define WRITE_RVC_RS2S(value) WRITE_REG(insn.rvc_rs2s(), value) +#define RVC_RS1 READ_REG(insn.rvc_rs1()) +#define RVC_RS2 READ_REG(insn.rvc_rs2()) +#define RVC_RS1S READ_REG(insn.rvc_rs1s()) +#define RVC_RS2S READ_REG(insn.rvc_rs2s()) +#define RVC_SP READ_REG(X_SP) // FPU macros #define FRS1 STATE.FPR[insn.rs1()] @@ -162,12 +172,13 @@ private: #define get_field(reg, mask) (((reg) & (decltype(reg))(mask)) / ((mask) & ~((mask) << 1))) #define set_field(reg, mask, val) (((reg) & ~(decltype(reg))(mask)) | (((decltype(reg))(val) * ((mask) & ~((mask) << 1))) & (decltype(reg))(mask))) -#define require_privilege(p) if (get_field(STATE.mstatus, MSTATUS_PRV) < (p)) throw trap_illegal_instruction() -#define require_rv64 if(unlikely(xlen != 64)) throw trap_illegal_instruction() -#define require_rv32 if(unlikely(xlen != 32)) throw trap_illegal_instruction() -#define require_extension(s) if (!p->supports_extension(s)) throw trap_illegal_instruction() -#define require_fp if (unlikely((STATE.mstatus & MSTATUS_FS) == 0)) throw trap_illegal_instruction() -#define require_accelerator if (unlikely((STATE.mstatus & MSTATUS_XS) == 0)) throw trap_illegal_instruction() +#define require(x) if (unlikely(!(x))) throw trap_illegal_instruction() +#define require_privilege(p) require(get_field(STATE.mstatus, MSTATUS_PRV) >= (p)) +#define require_rv64 require(xlen == 64) +#define require_rv32 require(xlen == 32) +#define require_extension(s) require(p->supports_extension(s)) +#define require_fp require((STATE.mstatus & MSTATUS_FS) != 0) +#define require_accelerator require((STATE.mstatus & MSTATUS_XS) != 0) #define set_fp_exceptions ({ STATE.fflags |= softfloat_exceptionFlags; \ softfloat_exceptionFlags = 0; }) diff --git a/riscv/encoding.h b/riscv/encoding.h index 1fcfaea..cfe8b38 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -221,47 +221,63 @@ #define MASK_BLTU 0x707f #define MATCH_BNE 0x1063 #define MASK_BNE 0x707f -#define MATCH_C_ADD 0x6000 +#define MATCH_C_ADD 0x1000 #define MASK_C_ADD 0xf003 -#define MATCH_C_ADDI 0x8000 +#define MATCH_C_ADD3 0xa000 +#define MASK_C_ADD3 0xe063 +#define MATCH_C_ADDI 0xc002 #define MASK_C_ADDI 0xe003 -#define MATCH_C_ADDI4 0xa000 -#define MASK_C_ADDI4 0xe003 -#define MATCH_C_ADDIW 0xe000 +#define MATCH_C_ADDI4SPN 0xa001 +#define MASK_C_ADDI4SPN 0xe003 +#define MATCH_C_ADDIW 0xe002 #define MASK_C_ADDIW 0xe003 -#define MATCH_C_ADDW 0x7000 +#define MATCH_C_ADDW 0x9000 #define MASK_C_ADDW 0xf003 -#define MATCH_C_BEQZ 0x2002 +#define MATCH_C_AND3 0xa060 +#define MASK_C_AND3 0xe063 +#define MATCH_C_BEQZ 0x4002 #define MASK_C_BEQZ 0xe003 #define MATCH_C_BNEZ 0x6002 #define MASK_C_BNEZ 0xe003 -#define MATCH_C_J 0xa002 +#define MATCH_C_J 0x2 #define MASK_C_J 0xe003 -#define MATCH_C_JALR 0x5000 -#define MASK_C_JALR 0xf003 -#define MATCH_C_LD 0x2001 +#define MATCH_C_JAL 0x2002 +#define MASK_C_JAL 0xe003 +#define MATCH_C_LD 0xe000 #define MASK_C_LD 0xe003 -#define MATCH_C_LDSP 0xc001 +#define MATCH_C_LDSP 0xe001 #define MASK_C_LDSP 0xe003 -#define MATCH_C_LI 0x0 +#define MATCH_C_LI 0x8002 #define MASK_C_LI 0xe003 -#define MATCH_C_LUI 0x2000 +#define MATCH_C_LUI 0xa002 #define MASK_C_LUI 0xe003 -#define MATCH_C_LW 0x1 +#define MATCH_C_LW 0xc000 #define MASK_C_LW 0xe003 -#define MATCH_C_LWSP 0x8001 +#define MATCH_C_LWSP 0xc001 #define MASK_C_LWSP 0xe003 -#define MATCH_C_MV 0x4000 +#define MATCH_C_MV 0x0 #define MASK_C_MV 0xf003 -#define MATCH_C_SD 0x6001 +#define MATCH_C_OR3 0xa040 +#define MASK_C_OR3 0xe063 +#define MATCH_C_SD 0x6000 #define MASK_C_SD 0xe003 -#define MATCH_C_SDSP 0xe001 +#define MATCH_C_SDSP 0x6001 #define MASK_C_SDSP 0xe003 -#define MATCH_C_SLLI 0xc000 +#define MATCH_C_SLLI 0x1 #define MASK_C_SLLI 0xe003 -#define MATCH_C_SW 0x4001 +#define MATCH_C_SLLIW 0x8001 +#define MASK_C_SLLIW 0xf003 +#define MATCH_C_SRAI 0x2000 +#define MASK_C_SRAI 0xe003 +#define MATCH_C_SRLI 0x2001 +#define MASK_C_SRLI 0xe003 +#define MATCH_C_SUB 0x8000 +#define MASK_C_SUB 0xf003 +#define MATCH_C_SUB3 0xa020 +#define MASK_C_SUB3 0xe063 +#define MATCH_C_SW 0x4000 #define MASK_C_SW 0xe003 -#define MATCH_C_SWSP 0xa001 +#define MATCH_C_SWSP 0x4001 #define MASK_C_SWSP 0xe003 #define MATCH_CSRRC 0x3073 #define MASK_CSRRC 0x707f @@ -637,14 +653,16 @@ DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(c_add3, MATCH_C_ADD3, MASK_C_ADD3) DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) -DECLARE_INSN(c_addi4, MATCH_C_ADDI4, MASK_C_ADDI4) +DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) +DECLARE_INSN(c_and3, MATCH_C_AND3, MASK_C_AND3) DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) -DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) +DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) @@ -652,9 +670,15 @@ DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) +DECLARE_INSN(c_or3, MATCH_C_OR3, MASK_C_OR3) DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(c_slliw, MATCH_C_SLLIW, MASK_C_SLLIW) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(c_sub3, MATCH_C_SUB3, MASK_C_SUB3) DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) diff --git a/riscv/insns/c_add.h b/riscv/insns/c_add.h index c349fc0..64bc5f7 100644 --- a/riscv/insns/c_add.h +++ b/riscv/insns/c_add.h @@ -1,2 +1,7 @@ require_extension('C'); -WRITE_RD(sext_xlen(RVC_RS1 + RVC_RS2)); +require(insn.rvc_rs2() != 0); +if (insn.rvc_rd() == 0) { // c.ebreak + throw trap_breakpoint(); +} else { + WRITE_RD(sext_xlen(RVC_RS1 + RVC_RS2)); +} diff --git a/riscv/insns/c_add3.h b/riscv/insns/c_add3.h new file mode 100644 index 0000000..fabf6dd --- /dev/null +++ b/riscv/insns/c_add3.h @@ -0,0 +1,2 @@ +require_extension('C'); +WRITE_RVC_RDS(sext_xlen(RVC_RS1S + RVC_RS2S)); diff --git a/riscv/insns/c_addi.h b/riscv/insns/c_addi.h index ad278f1..cea2a18 100644 --- a/riscv/insns/c_addi.h +++ b/riscv/insns/c_addi.h @@ -1,2 +1,7 @@ require_extension('C'); -WRITE_RD(sext_xlen(RVC_RS2 + insn.rvc_imm())); +if (insn.rvc_rd() == 0) { // c.addi16sp + WRITE_REG(X_SP, sext_xlen(RVC_SP + insn.rvc_addi16sp_imm())); +} else { + require(insn.rvc_imm() != 0); + WRITE_RD(sext_xlen(RVC_RS1 + insn.rvc_imm())); +} diff --git a/riscv/insns/c_addi4spn.h b/riscv/insns/c_addi4spn.h new file mode 100644 index 0000000..102fb25 --- /dev/null +++ b/riscv/insns/c_addi4spn.h @@ -0,0 +1,2 @@ +require_extension('C'); +WRITE_RVC_RS2S(sext_xlen(RVC_SP + insn.rvc_addi4spn_imm())); diff --git a/riscv/insns/c_addiw.h b/riscv/insns/c_addiw.h index 1b81834..27ffd8f 100644 --- a/riscv/insns/c_addiw.h +++ b/riscv/insns/c_addiw.h @@ -1,3 +1,4 @@ require_extension('C'); require_rv64; -WRITE_RD(sext32(RVC_RS2 + insn.rvc_imm())); +require(insn.rvc_rd() != 0); +WRITE_RD(sext32(RVC_RS1 + insn.rvc_imm())); diff --git a/riscv/insns/c_addw.h b/riscv/insns/c_addw.h index fef554d..36559b7 100644 --- a/riscv/insns/c_addw.h +++ b/riscv/insns/c_addw.h @@ -1,3 +1,4 @@ require_extension('C'); require_rv64; +require(insn.rvc_rd() != 0 && insn.rvc_rs2() != 0); WRITE_RD(sext32(RVC_RS1 + RVC_RS2)); diff --git a/riscv/insns/c_and3.h b/riscv/insns/c_and3.h new file mode 100644 index 0000000..5543950 --- /dev/null +++ b/riscv/insns/c_and3.h @@ -0,0 +1,2 @@ +require_extension('C'); +WRITE_RVC_RDS(RVC_RS1S & RVC_RS2S); diff --git a/riscv/insns/c_jal.h b/riscv/insns/c_jal.h new file mode 100644 index 0000000..b63967c --- /dev/null +++ b/riscv/insns/c_jal.h @@ -0,0 +1,4 @@ +require_extension('C'); +reg_t tmp = npc; +set_pc(pc + insn.rvc_j_imm()); +WRITE_REG(X_RA, tmp); diff --git a/riscv/insns/c_ld.h b/riscv/insns/c_ld.h index df0f5c3..876badd 100644 --- a/riscv/insns/c_ld.h +++ b/riscv/insns/c_ld.h @@ -1,3 +1,3 @@ require_extension('C'); require_rv64; -WRITE_RVC_RDS(MMU.load_int64(RVC_RS1S + insn.rvc_ld_imm())); +WRITE_RVC_RS2S(MMU.load_int64(RVC_RS1S + insn.rvc_ld_imm())); diff --git a/riscv/insns/c_ldsp.h b/riscv/insns/c_ldsp.h index 42665cf..7047d53 100644 --- a/riscv/insns/c_ldsp.h +++ b/riscv/insns/c_ldsp.h @@ -1,3 +1,4 @@ require_extension('C'); require_rv64; +require(insn.rvc_rd() != 0); WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm())); diff --git a/riscv/insns/c_li.h b/riscv/insns/c_li.h index 06d7bf2..52e99c9 100644 --- a/riscv/insns/c_li.h +++ b/riscv/insns/c_li.h @@ -1,7 +1,7 @@ require_extension('C'); -if (insn.rvc_rd() == 0) { - if (insn.rvc_imm() == -32) // c.sbreak - throw trap_breakpoint(); - throw trap_illegal_instruction(); -} else // c.li +require(insn.rvc_rd() != 0); +if (insn.rvc_imm() == 0) { // c.jr + set_pc(RVC_RS1 & ~reg_t(1)); +} else { WRITE_RD(insn.rvc_imm()); +} diff --git a/riscv/insns/c_lui.h b/riscv/insns/c_lui.h index 4bd4f87..040d7ec 100644 --- a/riscv/insns/c_lui.h +++ b/riscv/insns/c_lui.h @@ -1,2 +1,9 @@ require_extension('C'); -WRITE_RD(insn.rvc_imm() << 12); +require(insn.rvc_rd() != 0); +if (insn.rvc_imm() == 0) { // c.jalr + reg_t tmp = npc; + set_pc(RVC_RS1 & ~reg_t(1)); + WRITE_REG(X_RA, tmp); +} else { + WRITE_RD(insn.rvc_imm() << 12); +} diff --git a/riscv/insns/c_lw.h b/riscv/insns/c_lw.h index f2fc299..ef49dd9 100644 --- a/riscv/insns/c_lw.h +++ b/riscv/insns/c_lw.h @@ -1,2 +1,2 @@ require_extension('C'); -WRITE_RVC_RDS(MMU.load_int32(RVC_RS1S + insn.rvc_lw_imm())); +WRITE_RVC_RS2S(MMU.load_int32(RVC_RS1S + insn.rvc_lw_imm())); diff --git a/riscv/insns/c_lwsp.h b/riscv/insns/c_lwsp.h index ed4dcf3..b3d74db 100644 --- a/riscv/insns/c_lwsp.h +++ b/riscv/insns/c_lwsp.h @@ -1,2 +1,3 @@ require_extension('C'); +require(insn.rvc_rd() != 0); WRITE_RD(MMU.load_int32(RVC_SP + insn.rvc_lwsp_imm())); diff --git a/riscv/insns/c_mv.h b/riscv/insns/c_mv.h index bc05cfe..df5cea6 100644 --- a/riscv/insns/c_mv.h +++ b/riscv/insns/c_mv.h @@ -1,2 +1,3 @@ require_extension('C'); -WRITE_RD(RVC_RS1); +require(insn.rvc_rd() != 0); +WRITE_RD(RVC_RS2); diff --git a/riscv/insns/c_or3.h b/riscv/insns/c_or3.h new file mode 100644 index 0000000..8596223 --- /dev/null +++ b/riscv/insns/c_or3.h @@ -0,0 +1,2 @@ +require_extension('C'); +WRITE_RVC_RDS(RVC_RS1S | RVC_RS2S); diff --git a/riscv/insns/c_sdsp.h b/riscv/insns/c_sdsp.h index e8b5170..e59e00b 100644 --- a/riscv/insns/c_sdsp.h +++ b/riscv/insns/c_sdsp.h @@ -1,3 +1,3 @@ require_extension('C'); require_rv64; -MMU.store_uint64(RVC_SP + insn.rvc_ldsp_imm(), RVC_RS2); +MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2); diff --git a/riscv/insns/c_slli.h b/riscv/insns/c_slli.h index de3683b..6bbefb1 100644 --- a/riscv/insns/c_slli.h +++ b/riscv/insns/c_slli.h @@ -1,4 +1,3 @@ require_extension('C'); -if (insn.rvc_imm() >= xlen) - throw trap_illegal_instruction(); -WRITE_RD(sext_xlen(RVC_RS2 << insn.rvc_imm())); +require(insn.rvc_imm() < xlen); +WRITE_RD(sext_xlen(RVC_RS1 << insn.rvc_imm())); diff --git a/riscv/insns/c_slliw.h b/riscv/insns/c_slliw.h new file mode 100644 index 0000000..b2d87ef --- /dev/null +++ b/riscv/insns/c_slliw.h @@ -0,0 +1,3 @@ +require_extension('C'); +require_rv64; +WRITE_RD(sext_xlen(RVC_RS1 << insn.rvc_imm())); diff --git a/riscv/insns/c_srai.h b/riscv/insns/c_srai.h new file mode 100644 index 0000000..87d7b59 --- /dev/null +++ b/riscv/insns/c_srai.h @@ -0,0 +1,3 @@ +require_extension('C'); +require(insn.rvc_imm() < xlen); +WRITE_RD(sext_xlen(sext_xlen(RVC_RS1) >> insn.rvc_imm())); diff --git a/riscv/insns/c_srli.h b/riscv/insns/c_srli.h new file mode 100644 index 0000000..bf29f5f --- /dev/null +++ b/riscv/insns/c_srli.h @@ -0,0 +1,3 @@ +require_extension('C'); +require(insn.rvc_imm() < xlen); +WRITE_RD(sext_xlen(zext_xlen(RVC_RS1) >> insn.rvc_imm())); diff --git a/riscv/insns/c_sub.h b/riscv/insns/c_sub.h new file mode 100644 index 0000000..993fdd3 --- /dev/null +++ b/riscv/insns/c_sub.h @@ -0,0 +1,3 @@ +require_extension('C'); +require(insn.rvc_rd() != 0 && insn.rvc_rs2() != 0); +WRITE_RD(sext_xlen(RVC_RS1 - RVC_RS2)); diff --git a/riscv/insns/c_sub3.h b/riscv/insns/c_sub3.h new file mode 100644 index 0000000..50ed2c9 --- /dev/null +++ b/riscv/insns/c_sub3.h @@ -0,0 +1,2 @@ +require_extension('C'); +WRITE_RVC_RDS(sext_xlen(RVC_RS1S - RVC_RS2S)); diff --git a/riscv/insns/c_swsp.h b/riscv/insns/c_swsp.h index 6f3fef0..b8995ab 100644 --- a/riscv/insns/c_swsp.h +++ b/riscv/insns/c_swsp.h @@ -1,2 +1,2 @@ require_extension('C'); -MMU.store_uint32(RVC_SP + insn.rvc_lwsp_imm(), RVC_RS2); +MMU.store_uint32(RVC_SP + insn.rvc_swsp_imm(), RVC_RS2); diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc index 275fb56..e6336d0 100644 --- a/spike_main/disasm.cc +++ b/spike_main/disasm.cc @@ -128,9 +128,9 @@ struct : public arg_t { struct : public arg_t { std::string to_string(insn_t insn) const { - return xpr_name[insn.rvc_rds()]; + return xpr_name[insn.rvc_rs2()]; } -} rvc_rds; +} rvc_rs2; struct : public arg_t { std::string to_string(insn_t insn) const { @@ -138,12 +138,42 @@ struct : public arg_t { } } rvc_rs1s; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return xpr_name[insn.rvc_rs2s()]; + } +} rvc_rs2s; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return xpr_name[insn.rvc_rds()]; + } +} rvc_rds; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return xpr_name[X_SP]; + } +} rvc_sp; + struct : public arg_t { std::string to_string(insn_t insn) const { return std::to_string((int)insn.rvc_imm()); } } rvc_imm; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.rvc_addi4spn_imm()); + } +} rvc_addi4spn_imm; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.rvc_addi16sp_imm()); + } +} rvc_addi16sp_imm; + struct : public arg_t { std::string to_string(insn_t insn) const { return std::to_string((int)insn.rvc_lwsp_imm()); @@ -166,16 +196,28 @@ struct : public arg_t { struct : public arg_t { std::string to_string(insn_t insn) const { - return std::to_string((int)insn.rvc_lwsp_imm()) + '(' + xpr_name[2] + ')'; + return std::to_string((int)insn.rvc_lwsp_imm()) + '(' + xpr_name[X_SP] + ')'; } } rvc_lwsp_address; struct : public arg_t { std::string to_string(insn_t insn) const { - return std::to_string((int)insn.rvc_ldsp_imm()) + '(' + xpr_name[2] + ')'; + return std::to_string((int)insn.rvc_ldsp_imm()) + '(' + xpr_name[X_SP] + ')'; } } rvc_ldsp_address; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.rvc_swsp_imm()) + '(' + xpr_name[X_SP] + ')'; + } +} rvc_swsp_address; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.rvc_sdsp_imm()) + '(' + xpr_name[X_SP] + ')'; + } +} rvc_sdsp_address; + struct : public arg_t { std::string to_string(insn_t insn) const { return std::to_string((int)insn.rvc_lw_imm()) + '(' + xpr_name[insn.rvc_rs1s()] + ')'; @@ -220,11 +262,11 @@ disassembler_t::disassembler_t() const uint32_t match_rd_ra = 1UL << 7; const uint32_t mask_rs1 = 0x1fUL << 15; const uint32_t match_rs1_ra = 1UL << 15; - const uint32_t mask_rvc_rs1 = 0x1fUL << 2; - const uint32_t match_rvc_rs1_ra = 1UL << 2; const uint32_t mask_rs2 = 0x1fUL << 20; const uint32_t mask_imm = 0xfffUL << 20; const uint32_t match_imm_1 = 1UL << 20; + const uint32_t mask_rvc_rs2 = 0x1fUL << 2; + const uint32_t mask_rvc_imm = mask_rvc_rs2 | 0x1000UL; #define DECLARE_INSN(code, match, mask) \ const uint32_t match_##code = match; \ @@ -456,29 +498,31 @@ disassembler_t::disassembler_t() DEFINE_FXTYPE(flt_d); DEFINE_FXTYPE(fle_d); - add_insn(new disasm_insn_t("sbreak", match_c_li | 0x1000, 0xffff, {})); + DISASM_INSN("ebreak", c_add, mask_rd | mask_rvc_rs2, {}); + add_insn(new disasm_insn_t("ret", match_c_li | match_rd_ra, mask_c_li | mask_rd | mask_rvc_imm, {})); + DISASM_INSN("jr", c_li, mask_rvc_imm, {&rvc_rs1}); + DISASM_INSN("jalr", c_lui, mask_rvc_imm, {&rvc_rs1}); + DISASM_INSN("nop", c_addi, mask_rd | mask_rvc_imm, {}); + DISASM_INSN("addi", c_addi, mask_rd, {&rvc_sp, &rvc_sp, &rvc_addi16sp_imm}); + DISASM_INSN("addi", c_addi4spn, 0, {&rvc_rs1s, &rvc_sp, &rvc_addi4spn_imm}); DISASM_INSN("li", c_li, 0, {&xrd, &rvc_imm}); DISASM_INSN("lui", c_lui, 0, {&xrd, &rvc_uimm}); DISASM_INSN("addi", c_addi, 0, {&xrd, &xrd, &rvc_imm}); DISASM_INSN("addiw", c_addiw, 0, {&xrd, &xrd, &rvc_imm}); DISASM_INSN("slli", c_slli, 0, {&xrd, &rvc_shamt}); - DISASM_INSN("addi", c_addi4, 0, {&xrd, &xrd, &rvc_lwsp_imm}); DISASM_INSN("mv", c_mv, 0, {&xrd, &rvc_rs1}); - add_insn(new disasm_insn_t("ret", match_c_jalr | match_rvc_rs1_ra, mask_c_jalr | mask_rd | mask_rvc_rs1, {})); - DISASM_INSN("jr", c_jalr, mask_rd, {&xrd, &rvc_rs1}); - DISASM_INSN("jalr", c_jalr, mask_rd, {&xrd, &rvc_rs1}); DISASM_INSN("add", c_add, 0, {&xrd, &xrd, &rvc_rs1}); DISASM_INSN("addw", c_addw, 0, {&xrd, &xrd, &rvc_rs1}); DISASM_INSN("lw", c_lwsp, 0, {&xrd, &rvc_lwsp_address}); DISASM_INSN("ld", c_ldsp, 0, {&xrd, &rvc_ldsp_address}); - DISASM_INSN("sw", c_swsp, 0, {&xrd, &rvc_lwsp_address}); - DISASM_INSN("sd", c_sdsp, 0, {&xrd, &rvc_ldsp_address}); - DISASM_INSN("lw", c_lw, 0, {&rvc_rds, &rvc_lw_address}); - DISASM_INSN("ld", c_ld, 0, {&rvc_rds, &rvc_ld_address}); - DISASM_INSN("sw", c_sw, 0, {&rvc_rds, &rvc_lw_address}); - DISASM_INSN("sd", c_sd, 0, {&rvc_rds, &rvc_ld_address}); - DISASM_INSN("beqz", c_beqz, 0, {&rvc_rds, &rvc_branch_target}); - DISASM_INSN("bnez", c_bnez, 0, {&rvc_rds, &rvc_branch_target}); + DISASM_INSN("sw", c_swsp, 0, {&rvc_rs2, &rvc_swsp_address}); + DISASM_INSN("sd", c_sdsp, 0, {&rvc_rs2, &rvc_sdsp_address}); + DISASM_INSN("lw", c_lw, 0, {&rvc_rs2s, &rvc_lw_address}); + DISASM_INSN("ld", c_ld, 0, {&rvc_rs2s, &rvc_ld_address}); + DISASM_INSN("sw", c_sw, 0, {&rvc_rs2s, &rvc_lw_address}); + DISASM_INSN("sd", c_sd, 0, {&rvc_rs2s, &rvc_ld_address}); + DISASM_INSN("beqz", c_beqz, 0, {&rvc_rs1s, &rvc_branch_target}); + DISASM_INSN("bnez", c_bnez, 0, {&rvc_rs1s, &rvc_branch_target}); DISASM_INSN("j", c_j, 0, {&rvc_jump_target}); // provide a default disassembly for all instructions as a fallback -- 2.30.2