diff options
Diffstat (limited to 'riscv/insns')
54 files changed, 113 insertions, 76 deletions
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); |