From 21ce327f5d60d6805b5d9328b68f7ad2c261a859 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 18 Jan 2011 17:51:52 -0800 Subject: [PATCH] [opcodes, sim, xcc] made *w insns illegal in RV32 now generic variants behave differently in RV32 and RV64. --- riscv/decode.h | 57 +++++++++++++++++------------------------- riscv/execute.h | 10 -------- riscv/insns/add.h | 3 +-- riscv/insns/addi.h | 3 +-- riscv/insns/addiw.h | 1 + riscv/insns/addw.h | 2 +- riscv/insns/amo_add.h | 2 +- riscv/insns/amo_and.h | 2 +- riscv/insns/amo_max.h | 2 +- riscv/insns/amo_maxu.h | 2 +- riscv/insns/amo_min.h | 2 +- riscv/insns/amo_minu.h | 2 +- riscv/insns/amo_or.h | 2 +- riscv/insns/amo_swap.h | 2 +- riscv/insns/cvt_d_l.h | 2 +- riscv/insns/cvt_l_d.h | 2 +- riscv/insns/cvt_l_s.h | 2 +- riscv/insns/cvt_s_l.h | 2 +- riscv/insns/cvtu_d_l.h | 2 +- riscv/insns/cvtu_l_d.h | 2 +- riscv/insns/cvtu_l_s.h | 2 +- riscv/insns/cvtu_s_l.h | 2 +- riscv/insns/div.h | 10 +++++--- riscv/insns/divu.h | 3 +-- riscv/insns/divuw.h | 7 +++--- riscv/insns/divw.h | 9 ++++--- riscv/insns/ld.h | 2 +- riscv/insns/mfcr.h | 2 +- riscv/insns/mff_d.h | 2 +- riscv/insns/mfpcr.h | 2 +- riscv/insns/mtf_d.h | 2 +- riscv/insns/mul.h | 3 +-- riscv/insns/mulh.h | 12 ++++++--- riscv/insns/mulhu.h | 6 +++-- riscv/insns/mulhuw.h | 2 -- riscv/insns/mulhw.h | 2 -- riscv/insns/mulw.h | 2 +- riscv/insns/rem.h | 7 +++--- riscv/insns/remu.h | 5 ++-- riscv/insns/remuw.h | 7 +++--- riscv/insns/remw.h | 9 +++++-- riscv/insns/sd.h | 2 +- riscv/insns/sll.h | 3 +-- riscv/insns/slli.h | 10 ++++++-- riscv/insns/slliw.h | 1 + riscv/insns/sllw.h | 1 + riscv/insns/sra.h | 3 +-- riscv/insns/srai.h | 10 ++++++-- riscv/insns/sraiw.h | 1 + riscv/insns/sraw.h | 1 + riscv/insns/srl.h | 6 +++-- riscv/insns/srli.h | 10 ++++++-- riscv/insns/srliw.h | 1 + riscv/insns/srlw.h | 1 + riscv/insns/sub.h | 3 +-- riscv/insns/subw.h | 1 + riscv/processor.cc | 22 ++++++++-------- riscv/processor.h | 8 +++--- riscv/sim.cc | 6 ++--- 59 files changed, 155 insertions(+), 137 deletions(-) delete mode 100644 riscv/insns/mulhuw.h delete mode 100644 riscv/insns/mulhw.h diff --git a/riscv/decode.h b/riscv/decode.h index 5348ccc..fff6e0e 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -6,19 +6,6 @@ #include "config.h" -#ifdef RISCV_ENABLE_64BIT -# define support_64bit 1 -#else -# define support_64bit 0 -#endif - -#ifdef RISCV_ENABLE_FPU -# define support_fp 1 -#else -# define support_fp 0 -#endif - - typedef int int128_t __attribute__((mode(TI))); typedef unsigned int uint128_t __attribute__((mode(TI))); @@ -28,9 +15,8 @@ typedef uint64_t freg_t; const int OPCODE_BITS = 7; -const int GPR_BITS = 8*sizeof(reg_t); -const int GPRID_BITS = 5; -const int NGPR = 1 << GPRID_BITS; +const int XPRID_BITS = 5; +const int NXPR = 1 << XPRID_BITS; const int FPR_BITS = 64; const int FPRID_BITS = 5; @@ -87,8 +73,8 @@ struct itype_t unsigned opcode : OPCODE_BITS; unsigned funct : FUNCT_BITS; signed imm12 : IMM_BITS; - unsigned rs1 : GPRID_BITS; - unsigned rd : GPRID_BITS; + unsigned rs1 : XPRID_BITS; + unsigned rd : XPRID_BITS; }; struct btype_t @@ -96,8 +82,8 @@ struct btype_t unsigned opcode : OPCODE_BITS; unsigned funct : FUNCT_BITS; unsigned immlo : IMMLO_BITS; - unsigned rs2 : GPRID_BITS; - unsigned rs1 : GPRID_BITS; + unsigned rs2 : XPRID_BITS; + unsigned rs1 : XPRID_BITS; signed immhi : IMM_BITS-IMMLO_BITS; }; @@ -112,16 +98,16 @@ struct rtype_t unsigned opcode : OPCODE_BITS; unsigned funct : FUNCT_BITS; unsigned functr : FUNCTR_BITS; - unsigned rs2 : GPRID_BITS; - unsigned rs1 : GPRID_BITS; - unsigned rd : GPRID_BITS; + unsigned rs2 : XPRID_BITS; + unsigned rs1 : XPRID_BITS; + unsigned rd : XPRID_BITS; }; struct ltype_t { unsigned opcode : OPCODE_BITS; unsigned bigimm : BIGIMM_BITS; - unsigned rd : GPRID_BITS; + unsigned rd : XPRID_BITS; }; struct ftype_t @@ -170,14 +156,14 @@ private: #endif // helpful macros, etc -#define RS1 R[insn.rtype.rs1] -#define RS2 R[insn.rtype.rs2] -#define RD do_writeback(R,insn.rtype.rd) -#define RA do_writeback(R,1) -#define FRS1 FR[insn.ftype.rs1] -#define FRS2 FR[insn.ftype.rs2] -#define FRS3 FR[insn.ftype.rs3] -#define FRD FR[insn.ftype.rd] +#define RS1 XPR[insn.rtype.rs1] +#define RS2 XPR[insn.rtype.rs2] +#define RD do_writeback(XPR,insn.rtype.rd) +#define RA do_writeback(XPR,1) +#define FRS1 FPR[insn.ftype.rs1] +#define FRS2 FPR[insn.ftype.rs2] +#define FRS3 FPR[insn.ftype.rs3] +#define FRD FPR[insn.ftype.rd] #define BIGIMM insn.ltype.bigimm #define SIMM insn.itype.imm12 #define BIMM ((signed)insn.btype.immlo | (insn.btype.immhi << IMMLO_BITS)) @@ -190,9 +176,10 @@ private: ((fsr & FSR_RD) >> FSR_RD_SHIFT)) #define require_supervisor if(!(sr & SR_S)) throw trap_privileged_instruction -#define require64 if(gprlen != 64) throw trap_illegal_instruction +#define xpr64 (xprlen == 64) +#define require_xpr64 if(!xpr64) throw trap_illegal_instruction #define require_fp if(!(sr & SR_EF)) throw trap_fp_disabled -#define cmp_trunc(reg) (reg_t(reg) << (64-gprlen)) +#define cmp_trunc(reg) (reg_t(reg) << (64-xprlen)) #define set_fp_exceptions ({ set_fsr(fsr | \ (softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \ softfloat_exceptionFlags = 0; }) @@ -202,4 +189,6 @@ static inline sreg_t sext32(int32_t arg) return arg; } +#define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen)) + #endif diff --git a/riscv/execute.h b/riscv/execute.h index ddc7b42..b8e396a 100644 --- a/riscv/execute.h +++ b/riscv/execute.h @@ -768,11 +768,6 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/divuw.h" break; } - if((insn.bits & 0x1ffff) == 0xcf7) - { - #include "insns/mulhuw.h" - break; - } if((insn.bits & 0x1ffff) == 0xf7) { #include "insns/mulw.h" @@ -783,11 +778,6 @@ switch((insn.bits >> 0x0) & 0x7f) #include "insns/remw.h" break; } - if((insn.bits & 0x1ffff) == 0x8f7) - { - #include "insns/mulhw.h" - break; - } if((insn.bits & 0x1ffff) == 0x10f7) { #include "insns/divw.h" diff --git a/riscv/insns/add.h b/riscv/insns/add.h index a7ec78d..34d49ff 100644 --- a/riscv/insns/add.h +++ b/riscv/insns/add.h @@ -1,2 +1 @@ -require64; -RD = RS1 + RS2; +RD = sext_xprlen(RS1 + RS2); diff --git a/riscv/insns/addi.h b/riscv/insns/addi.h index 2b9bae3..88881e5 100644 --- a/riscv/insns/addi.h +++ b/riscv/insns/addi.h @@ -1,2 +1 @@ -require64; -RD = SIMM + RS1; +RD = sext_xprlen(RS1 + SIMM); diff --git a/riscv/insns/addiw.h b/riscv/insns/addiw.h index cf97d34..23ae278 100644 --- a/riscv/insns/addiw.h +++ b/riscv/insns/addiw.h @@ -1 +1,2 @@ +require_xpr64; RD = sext32(SIMM + RS1); diff --git a/riscv/insns/addw.h b/riscv/insns/addw.h index f8715e3..4e2ed56 100644 --- a/riscv/insns/addw.h +++ b/riscv/insns/addw.h @@ -1,2 +1,2 @@ +require_xpr64; RD = sext32(RS1 + RS2); - diff --git a/riscv/insns/amo_add.h b/riscv/insns/amo_add.h index 3b59ffd..b8450bf 100644 --- a/riscv/insns/amo_add.h +++ b/riscv/insns/amo_add.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; reg_t v = mmu.load_uint64(RS1); mmu.store_uint64(RS1, RS2 + v); RD = v; diff --git a/riscv/insns/amo_and.h b/riscv/insns/amo_and.h index 7295501..586eb7f 100644 --- a/riscv/insns/amo_and.h +++ b/riscv/insns/amo_and.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; reg_t v = mmu.load_uint64(RS1); mmu.store_uint64(RS1, RS2 & v); RD = v; diff --git a/riscv/insns/amo_max.h b/riscv/insns/amo_max.h index f67f1a3..1a0bc8a 100644 --- a/riscv/insns/amo_max.h +++ b/riscv/insns/amo_max.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; sreg_t v = mmu.load_int64(RS1); mmu.store_uint64(RS1, std::max(sreg_t(RS2),v)); RD = v; diff --git a/riscv/insns/amo_maxu.h b/riscv/insns/amo_maxu.h index 9a3d9f6..ccfaf1d 100644 --- a/riscv/insns/amo_maxu.h +++ b/riscv/insns/amo_maxu.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; reg_t v = mmu.load_uint64(RS1); mmu.store_uint64(RS1, std::max(RS2,v)); RD = v; diff --git a/riscv/insns/amo_min.h b/riscv/insns/amo_min.h index 4acfe74..4f3b6d6 100644 --- a/riscv/insns/amo_min.h +++ b/riscv/insns/amo_min.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; sreg_t v = mmu.load_int64(RS1); mmu.store_uint64(RS1, std::min(sreg_t(RS2),v)); RD = v; diff --git a/riscv/insns/amo_minu.h b/riscv/insns/amo_minu.h index 5af3b9d..c09c51a 100644 --- a/riscv/insns/amo_minu.h +++ b/riscv/insns/amo_minu.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; reg_t v = mmu.load_uint64(RS1); mmu.store_uint64(RS1, std::min(RS2,v)); RD = v; diff --git a/riscv/insns/amo_or.h b/riscv/insns/amo_or.h index df4f2fe..76a4508 100644 --- a/riscv/insns/amo_or.h +++ b/riscv/insns/amo_or.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; reg_t v = mmu.load_uint64(RS1); mmu.store_uint64(RS1, RS2 | v); RD = v; diff --git a/riscv/insns/amo_swap.h b/riscv/insns/amo_swap.h index 6889055..43e3538 100644 --- a/riscv/insns/amo_swap.h +++ b/riscv/insns/amo_swap.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; reg_t v = mmu.load_uint64(RS1); mmu.store_uint64(RS1, RS2); RD = v; diff --git a/riscv/insns/cvt_d_l.h b/riscv/insns/cvt_d_l.h index 84c1a71..68c0482 100644 --- a/riscv/insns/cvt_d_l.h +++ b/riscv/insns/cvt_d_l.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; require_fp; softfloat_roundingMode = RM; FRD = i64_to_f64(RS1); diff --git a/riscv/insns/cvt_l_d.h b/riscv/insns/cvt_l_d.h index 2747d67..bd460d5 100644 --- a/riscv/insns/cvt_l_d.h +++ b/riscv/insns/cvt_l_d.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; require_fp; softfloat_roundingMode = RM; RD = f64_to_i64_r_minMag(FRS1,true); diff --git a/riscv/insns/cvt_l_s.h b/riscv/insns/cvt_l_s.h index f5b053c..1ed4594 100644 --- a/riscv/insns/cvt_l_s.h +++ b/riscv/insns/cvt_l_s.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; require_fp; softfloat_roundingMode = RM; RD = f32_to_i64_r_minMag(FRS1,true); diff --git a/riscv/insns/cvt_s_l.h b/riscv/insns/cvt_s_l.h index 79fbc97..f149229 100644 --- a/riscv/insns/cvt_s_l.h +++ b/riscv/insns/cvt_s_l.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; require_fp; softfloat_roundingMode = RM; FRD = i64_to_f32(RS1); diff --git a/riscv/insns/cvtu_d_l.h b/riscv/insns/cvtu_d_l.h index 84c1a71..68c0482 100644 --- a/riscv/insns/cvtu_d_l.h +++ b/riscv/insns/cvtu_d_l.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; require_fp; softfloat_roundingMode = RM; FRD = i64_to_f64(RS1); diff --git a/riscv/insns/cvtu_l_d.h b/riscv/insns/cvtu_l_d.h index 2747d67..bd460d5 100644 --- a/riscv/insns/cvtu_l_d.h +++ b/riscv/insns/cvtu_l_d.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; require_fp; softfloat_roundingMode = RM; RD = f64_to_i64_r_minMag(FRS1,true); diff --git a/riscv/insns/cvtu_l_s.h b/riscv/insns/cvtu_l_s.h index f5b053c..1ed4594 100644 --- a/riscv/insns/cvtu_l_s.h +++ b/riscv/insns/cvtu_l_s.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; require_fp; softfloat_roundingMode = RM; RD = f32_to_i64_r_minMag(FRS1,true); diff --git a/riscv/insns/cvtu_s_l.h b/riscv/insns/cvtu_s_l.h index 79fbc97..f149229 100644 --- a/riscv/insns/cvtu_s_l.h +++ b/riscv/insns/cvtu_s_l.h @@ -1,4 +1,4 @@ -require64; +require_xpr64; require_fp; softfloat_roundingMode = RM; FRD = i64_to_f32(RS1); diff --git a/riscv/insns/div.h b/riscv/insns/div.h index 1f61cf1..aa67134 100644 --- a/riscv/insns/div.h +++ b/riscv/insns/div.h @@ -1,5 +1,9 @@ -require64; if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1)) - RD = sreg_t(RS1) < 0 ? INT64_MIN : INT64_MAX; +{ + if(xpr64) + RD = sreg_t(RS1) < 0 ? INT64_MIN : INT64_MAX; + else + RD = sreg_t(RS1) < 0 ? sext32(INT32_MIN) : INT32_MAX; +} else - RD = sreg_t(RS1) / sreg_t(RS2); + RD = sext_xprlen(sreg_t(RS1) / sreg_t(RS2)); diff --git a/riscv/insns/divu.h b/riscv/insns/divu.h index 86792a2..d4a4eca 100644 --- a/riscv/insns/divu.h +++ b/riscv/insns/divu.h @@ -1,5 +1,4 @@ -require64; if(RS2 == 0) RD = UINT64_MAX; else - RD = RS1 / RS2; + RD = sext_xprlen(RS1 / RS2); diff --git a/riscv/insns/divuw.h b/riscv/insns/divuw.h index 296bb9e..4d64be3 100644 --- a/riscv/insns/divuw.h +++ b/riscv/insns/divuw.h @@ -1,4 +1,5 @@ -if(uint32_t(RS2) == 0) - RD = sext32(UINT32_MAX); +require_xpr64; +if(RS2 == 0) + RD = UINT64_MAX; else - RD = sext32(uint32_t(RS1)/uint32_t(RS2)); + RD = sext32(RS1 / RS2); diff --git a/riscv/insns/divw.h b/riscv/insns/divw.h index bfc982a..9c732b5 100644 --- a/riscv/insns/divw.h +++ b/riscv/insns/divw.h @@ -1,4 +1,7 @@ -if(int32_t(RS2) == 0 || (int32_t(RS1) == INT32_MIN && int32_t(RS2) == -1)) - RD = sext32(int32_t(RS1) < 0 ? INT32_MIN : INT32_MAX); +require_xpr64; +// INT64_MIN/-1 corner case shouldn't occur in correct code, since +// INT64_MIN is not a proper 32-bit signed value +if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1)) + RD = sext32(sreg_t(RS1) < 0 ? INT32_MIN : INT32_MAX); else - RD = sext32(int32_t(RS1)/int32_t(RS2)); + RD = sext32(sreg_t(RS1) / sreg_t(RS2)); diff --git a/riscv/insns/ld.h b/riscv/insns/ld.h index 973a8b3..940d348 100644 --- a/riscv/insns/ld.h +++ b/riscv/insns/ld.h @@ -1,2 +1,2 @@ -require64; +require_xpr64; RD = mmu.load_int64(RS1+SIMM); diff --git a/riscv/insns/mfcr.h b/riscv/insns/mfcr.h index 6209e6f..f3bd81e 100644 --- a/riscv/insns/mfcr.h +++ b/riscv/insns/mfcr.h @@ -15,4 +15,4 @@ switch(insn.rtype.rs2) val = -1; } -RD = gprlen == 64 ? val : sext32(val); +RD = sext_xprlen(val); diff --git a/riscv/insns/mff_d.h b/riscv/insns/mff_d.h index ba53561..31be4cb 100644 --- a/riscv/insns/mff_d.h +++ b/riscv/insns/mff_d.h @@ -1,3 +1,3 @@ -require64; +require_xpr64; require_fp; RD = FRS2; diff --git a/riscv/insns/mfpcr.h b/riscv/insns/mfpcr.h index 54c62ed..e9d5350 100644 --- a/riscv/insns/mfpcr.h +++ b/riscv/insns/mfpcr.h @@ -45,4 +45,4 @@ switch(insn.rtype.rs2) val = -1; } -RD = gprlen == 64 ? val : sext32(val); +RD = sext_xprlen(val); diff --git a/riscv/insns/mtf_d.h b/riscv/insns/mtf_d.h index 44daa9e..29792ec 100644 --- a/riscv/insns/mtf_d.h +++ b/riscv/insns/mtf_d.h @@ -1,3 +1,3 @@ -require64; +require_xpr64; require_fp; FRD = RS1; diff --git a/riscv/insns/mul.h b/riscv/insns/mul.h index ff1e034..770d733 100644 --- a/riscv/insns/mul.h +++ b/riscv/insns/mul.h @@ -1,2 +1 @@ -require64; -RD = RS1 * RS2; +RD = sext_xprlen(RS1 * RS2); diff --git a/riscv/insns/mulh.h b/riscv/insns/mulh.h index ed9c1a8..ceefccd 100644 --- a/riscv/insns/mulh.h +++ b/riscv/insns/mulh.h @@ -1,4 +1,8 @@ -require64; -int64_t rb = RS1; -int64_t ra = RS2; -RD = (int128_t(rb) * int128_t(ra)) >> 64; +if(xpr64) +{ + int64_t a = RS1; + int64_t b = RS2; + RD = (int128_t(a) * int128_t(b)) >> 64; +} +else + RD = sext32((sreg_t(RS1) * sreg_t(RS2)) >> 32); diff --git a/riscv/insns/mulhu.h b/riscv/insns/mulhu.h index 17c610d..b6f45dd 100644 --- a/riscv/insns/mulhu.h +++ b/riscv/insns/mulhu.h @@ -1,2 +1,4 @@ -require64; -RD = (uint128_t(RS1) * uint128_t(RS2)) >> 64; +if(xpr64) + RD = (uint128_t(RS1) * uint128_t(RS2)) >> 64; +else + RD = sext32((RS1 * RS2) >> 32); diff --git a/riscv/insns/mulhuw.h b/riscv/insns/mulhuw.h deleted file mode 100644 index 9260a24..0000000 --- a/riscv/insns/mulhuw.h +++ /dev/null @@ -1,2 +0,0 @@ -RD = sext32((RS1 * RS2) >> 32); - diff --git a/riscv/insns/mulhw.h b/riscv/insns/mulhw.h deleted file mode 100644 index a47aa1e..0000000 --- a/riscv/insns/mulhw.h +++ /dev/null @@ -1,2 +0,0 @@ -RD = sext32((sreg_t(RS1) * sreg_t(RS2)) >> 32); - diff --git a/riscv/insns/mulw.h b/riscv/insns/mulw.h index 81285a2..7b0a934 100644 --- a/riscv/insns/mulw.h +++ b/riscv/insns/mulw.h @@ -1,2 +1,2 @@ +require_xpr64; RD = sext32(RS1 * RS2); - diff --git a/riscv/insns/rem.h b/riscv/insns/rem.h index 1bc94f2..db7e0a9 100644 --- a/riscv/insns/rem.h +++ b/riscv/insns/rem.h @@ -1,5 +1,6 @@ -require64; -if(RS2 == 0 || (sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1)) +if(RS2 == 0) + RD = RS1; +else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1) RD = 0; else - RD = sreg_t(RS1) % sreg_t(RS2); + RD = sext_xprlen(sreg_t(RS1) % sreg_t(RS2)); diff --git a/riscv/insns/remu.h b/riscv/insns/remu.h index 3b6c44f..04499ab 100644 --- a/riscv/insns/remu.h +++ b/riscv/insns/remu.h @@ -1,5 +1,4 @@ -require64; if(RS2 == 0) - RD = 0; + RD = RS1; else - RD = RS1 % RS2; + RD = sext_xprlen(RS1 % RS2); diff --git a/riscv/insns/remuw.h b/riscv/insns/remuw.h index 820a396..ae28fa5 100644 --- a/riscv/insns/remuw.h +++ b/riscv/insns/remuw.h @@ -1,4 +1,5 @@ -if(uint32_t(RS2) == 0) - RD = 0; +require_xpr64; +if(RS2 == 0) + RD = RS1; else - RD = sext32(uint32_t(RS1) % uint32_t(RS2)); + RD = sext32(RS1 % RS2); diff --git a/riscv/insns/remw.h b/riscv/insns/remw.h index eb23ef1..784baa3 100644 --- a/riscv/insns/remw.h +++ b/riscv/insns/remw.h @@ -1,4 +1,9 @@ -if(int32_t(RS2) == 0 || (int32_t(RS1) == INT32_MIN && int32_t(RS2) == -1)) +require_xpr64; +// INT64_MIN/-1 corner case shouldn't occur in correct code, since +// INT64_MIN is not a proper 32-bit signed value +if(RS2 == 0) + RD = RS1; +else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1) RD = 0; else - RD = sext32(int32_t(RS1) % int32_t(RS2)); + RD = sext32(sreg_t(RS1) % sreg_t(RS2)); diff --git a/riscv/insns/sd.h b/riscv/insns/sd.h index f4ece21..2009149 100644 --- a/riscv/insns/sd.h +++ b/riscv/insns/sd.h @@ -1,2 +1,2 @@ -require64; +require_xpr64; mmu.store_uint64(RS1+BIMM, RS2); diff --git a/riscv/insns/sll.h b/riscv/insns/sll.h index ae38f16..86eb966 100644 --- a/riscv/insns/sll.h +++ b/riscv/insns/sll.h @@ -1,2 +1 @@ -require64; -RD = RS1 << (RS2 & 0x3F); +RD = sext_xprlen(RS1 << (RS2 & (xprlen-1))); diff --git a/riscv/insns/slli.h b/riscv/insns/slli.h index f7ba310..bfaf430 100644 --- a/riscv/insns/slli.h +++ b/riscv/insns/slli.h @@ -1,2 +1,8 @@ -require64; -RD = RS1 << SHAMT; +if(xpr64) + RD = RS1 << SHAMT; +else +{ + if(SHAMT & 0x20) + throw trap_illegal_instruction; + RD = sext32(RS1 << SHAMT); +} diff --git a/riscv/insns/slliw.h b/riscv/insns/slliw.h index 41be30f..1f6e50d 100644 --- a/riscv/insns/slliw.h +++ b/riscv/insns/slliw.h @@ -1 +1,2 @@ +require_xpr64; RD = sext32(RS1 << SHAMTW); diff --git a/riscv/insns/sllw.h b/riscv/insns/sllw.h index 90e5c4c..f3356d8 100644 --- a/riscv/insns/sllw.h +++ b/riscv/insns/sllw.h @@ -1 +1,2 @@ +require_xpr64; RD = sext32(RS1 << (RS2 & 0x1F)); diff --git a/riscv/insns/sra.h b/riscv/insns/sra.h index 4a78916..8bbdc09 100644 --- a/riscv/insns/sra.h +++ b/riscv/insns/sra.h @@ -1,2 +1 @@ -require64; -RD = sreg_t(RS1) >> (RS2 & 0x3F); +RD = sext_xprlen(sreg_t(RS1) >> (RS2 & (xprlen-1))); diff --git a/riscv/insns/srai.h b/riscv/insns/srai.h index 1f0dde2..18fc55b 100644 --- a/riscv/insns/srai.h +++ b/riscv/insns/srai.h @@ -1,2 +1,8 @@ -require64; -RD = sreg_t(RS1) >> SHAMT; +if(xpr64) + RD = sreg_t(RS1) >> SHAMT; +else +{ + if(SHAMT & 0x20) + throw trap_illegal_instruction; + RD = sext32(sreg_t(RS1) >> SHAMT); +} diff --git a/riscv/insns/sraiw.h b/riscv/insns/sraiw.h index 24a9eae..42d0fc3 100644 --- a/riscv/insns/sraiw.h +++ b/riscv/insns/sraiw.h @@ -1 +1,2 @@ +require_xpr64; RD = sext32(sreg_t(RS1) >> SHAMTW); diff --git a/riscv/insns/sraw.h b/riscv/insns/sraw.h index f8946fb..103f03a 100644 --- a/riscv/insns/sraw.h +++ b/riscv/insns/sraw.h @@ -1 +1,2 @@ +require_xpr64; RD = sext32(sreg_t(RS1) >> (RS2 & 0x1F)); diff --git a/riscv/insns/srl.h b/riscv/insns/srl.h index 87138da..8230d27 100644 --- a/riscv/insns/srl.h +++ b/riscv/insns/srl.h @@ -1,2 +1,4 @@ -require64; -RD = RS1 >> (RS2 & 0x3F); +if(xpr64) + RD = RS1 >> (RS2 & 0x3F); +else + RD = sext32((uint32_t)RS1 >> (RS2 & 0x1F)); diff --git a/riscv/insns/srli.h b/riscv/insns/srli.h index e0d8ae0..5378fd1 100644 --- a/riscv/insns/srli.h +++ b/riscv/insns/srli.h @@ -1,2 +1,8 @@ -require64; -RD = RS1 >> SHAMT; +if(xpr64) + RD = RS1 >> SHAMT; +else +{ + if(SHAMT & 0x20) + throw trap_illegal_instruction; + RD = sext32((uint32_t)RS1 >> SHAMT); +} diff --git a/riscv/insns/srliw.h b/riscv/insns/srliw.h index 2a2bb31..c400507 100644 --- a/riscv/insns/srliw.h +++ b/riscv/insns/srliw.h @@ -1 +1,2 @@ +require_xpr64; RD = sext32((uint32_t)RS1 >> SHAMTW); diff --git a/riscv/insns/srlw.h b/riscv/insns/srlw.h index a0058ae..b206f7c 100644 --- a/riscv/insns/srlw.h +++ b/riscv/insns/srlw.h @@ -1 +1,2 @@ +require_xpr64; RD = sext32((uint32_t)RS1 >> (RS2 & 0x1F)); diff --git a/riscv/insns/sub.h b/riscv/insns/sub.h index e7736c9..2b1e057 100644 --- a/riscv/insns/sub.h +++ b/riscv/insns/sub.h @@ -1,2 +1 @@ -require64; -RD = RS1 - RS2; +RD = sext_xprlen(RS1 - RS2); diff --git a/riscv/insns/subw.h b/riscv/insns/subw.h index 958cc5d..28db334 100644 --- a/riscv/insns/subw.h +++ b/riscv/insns/subw.h @@ -1,2 +1,3 @@ +require_xpr64; RD = sext32(RS1 - RS2); diff --git a/riscv/processor.cc b/riscv/processor.cc index eed85da..6f36653 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -12,8 +12,8 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz) : sim(_sim), mmu(_mem,_memsz) { - memset(R,0,sizeof(R)); - memset(FR,0,sizeof(FR)); + memset(XPR,0,sizeof(XPR)); + memset(FPR,0,sizeof(FPR)); pc = 0; evec = 0; epc = 0; @@ -26,7 +26,7 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz) count = 0; compare = 0; interrupts_pending = 0; - set_sr(SR_S | (support_64bit ? SR_SX : 0)); + set_sr(SR_S | SR_SX); // SX ignored if 64b mode not supported set_fsr(0); memset(counters,0,sizeof(counters)); @@ -48,12 +48,14 @@ void processor_t::init(uint32_t _id) void processor_t::set_sr(uint32_t val) { sr = val & ~SR_ZERO; - if(!support_64bit) - sr &= ~(SR_SX | SR_UX); - if(!support_fp) - sr &= ~SR_EF; - - gprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32; +#ifndef RISCV_ENABLE_64BIT + sr &= ~(SR_SX | SR_UX); +#endif +#ifndef RISCV_ENABLE_64BIT + sr &= ~SR_EF; +#endif + + xprlen = ((sr & SR_S) ? (sr & SR_SX) : (sr & SR_UX)) ? 64 : 32; } void processor_t::set_fsr(uint32_t val) @@ -86,7 +88,7 @@ void processor_t::step(size_t n, bool noisy) #include "execute.h" pc = npc; - R[0] = 0; + XPR[0] = 0; if(count++ == compare) interrupts_pending |= 1 << TIMER_IRQ; diff --git a/riscv/processor.h b/riscv/processor.h index 9ccfbb4..b548038 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -19,8 +19,8 @@ private: sim_t* sim; // architected state - reg_t R[NGPR]; - freg_t FR[NFPR]; + reg_t XPR[NXPR]; + freg_t FPR[NFPR]; // privileged control registers reg_t pc; @@ -41,8 +41,8 @@ private: // unprivileged control registers uint32_t fsr; - // 32-bit or 64-bit mode (redundant with sr) - int gprlen; + // # of bits in an XPR (32 or 64). (redundant with sr) + int xprlen; // shared memory mmu_t mmu; diff --git a/riscv/sim.cc b/riscv/sim.cc index ffcb186..f788021 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -163,10 +163,10 @@ reg_t sim_t::get_reg(const std::vector& args) int p = atoi(args[0].c_str()); int r = atoi(args[1].c_str()); - if(p >= (int)procs.size() || r >= NGPR) + if(p >= (int)procs.size() || r >= NXPR) throw trap_illegal_instruction; - return procs[p].R[r]; + return procs[p].XPR[r]; } reg_t sim_t::get_freg(const std::vector& args) @@ -179,7 +179,7 @@ reg_t sim_t::get_freg(const std::vector& args) if(p >= (int)procs.size() || r >= NFPR) throw trap_illegal_instruction; - return procs[p].FR[r]; + return procs[p].FPR[r]; } reg_t sim_t::get_tohost(const std::vector& args) -- 2.30.2