From f7201358428076506c64bc38fca01db94b2be07a Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Tue, 19 May 2026 01:54:52 -0700 Subject: [PATCH 01/12] rvp: handle rv64 and rv32 overlap again Signed-off-by: Chih-Min Chao --- riscv/check-opcode-overlap.t.cc | 3 + riscv/overlap_list.h | 124 ++++++++++++++++---------------- riscv/processor.cc | 5 ++ 3 files changed, 70 insertions(+), 62 deletions(-) diff --git a/riscv/check-opcode-overlap.t.cc b/riscv/check-opcode-overlap.t.cc index e1a3b067..285aaded 100644 --- a/riscv/check-opcode-overlap.t.cc +++ b/riscv/check-opcode-overlap.t.cc @@ -33,8 +33,11 @@ int main() std::unordered_map overlap_list; #define DECLARE_OVERLAP_INSN(name, ext) \ overlap_list[std::string(#name)] = false; + #define DECLARE_OVERLAP_INSN_RV64(name, ext) \ + overlap_list[std::string(#name)] = false; #include "overlap_list.h" #undef DECLARE_OVERLAP_INSN + #undef DECLARE_OVERLAP_INSN_RV64 std::vector list; for (size_t i = 0; i < std::size(static_list); i++) { diff --git a/riscv/overlap_list.h b/riscv/overlap_list.h index bf9b72e7..3cab59f2 100644 --- a/riscv/overlap_list.h +++ b/riscv/overlap_list.h @@ -33,65 +33,65 @@ DECLARE_OVERLAP_INSN(c_sspush_x1, EXT_ZICFISS) DECLARE_OVERLAP_INSN(c_sspopchk_x5, EXT_ZICFISS) DECLARE_OVERLAP_INSN(c_mop_N, EXT_ZCMOP) -// rv64p overlap rv32p -DECLARE_OVERLAP_INSN(paadd_w, 'P') -DECLARE_OVERLAP_INSN(paaddu_w, 'P') -DECLARE_OVERLAP_INSN(pasub_w, 'P') -DECLARE_OVERLAP_INSN(pasubu_w, 'P') -DECLARE_OVERLAP_INSN(psadd_w, 'P') -DECLARE_OVERLAP_INSN(psaddu_w, 'P') -DECLARE_OVERLAP_INSN(pssh1sadd_w, 'P') -DECLARE_OVERLAP_INSN(pssub_w, 'P') -DECLARE_OVERLAP_INSN(pssubu_w, 'P') -DECLARE_OVERLAP_INSN(psati_w, 'P') -DECLARE_OVERLAP_INSN(pusati_w, 'P') -DECLARE_OVERLAP_INSN(psrari_w, 'P') -DECLARE_OVERLAP_INSN(pssha_ws, 'P') -DECLARE_OVERLAP_INSN(psshar_ws, 'P') -DECLARE_OVERLAP_INSN(psslai_w, 'P') -DECLARE_OVERLAP_INSN(pmseq_w, 'P') -DECLARE_OVERLAP_INSN(pmslt_w, 'P') -DECLARE_OVERLAP_INSN(pmsltu_w, 'P') -DECLARE_OVERLAP_INSN(pmul_w_h00, 'P') -DECLARE_OVERLAP_INSN(pmul_w_h01, 'P') -DECLARE_OVERLAP_INSN(pmul_w_h11, 'P') -DECLARE_OVERLAP_INSN(pmulh_w_h0, 'P') -DECLARE_OVERLAP_INSN(pmulh_w_h1, 'P') -DECLARE_OVERLAP_INSN(pmulhr_w, 'P') -DECLARE_OVERLAP_INSN(pmulhrsu_w, 'P') -DECLARE_OVERLAP_INSN(pmulhru_w, 'P') -DECLARE_OVERLAP_INSN(pmulhsu_w_h0, 'P') -DECLARE_OVERLAP_INSN(pmulhsu_w_h1, 'P') -DECLARE_OVERLAP_INSN(pmulq_w, 'P') -DECLARE_OVERLAP_INSN(pmulqr_w, 'P') -DECLARE_OVERLAP_INSN(pmulsu_w_h00, 'P') -DECLARE_OVERLAP_INSN(pmulsu_w_h11, 'P') -DECLARE_OVERLAP_INSN(pmulu_w_h00, 'P') -DECLARE_OVERLAP_INSN(pmulu_w_h01, 'P') -DECLARE_OVERLAP_INSN(pmulu_w_h11, 'P') -DECLARE_OVERLAP_INSN(pmacc_w_h00, 'P') -DECLARE_OVERLAP_INSN(pmacc_w_h01, 'P') -DECLARE_OVERLAP_INSN(pmacc_w_h11, 'P') -DECLARE_OVERLAP_INSN(pmaccsu_w_h00, 'P') -DECLARE_OVERLAP_INSN(pmaccsu_w_h11, 'P') -DECLARE_OVERLAP_INSN(pmaccu_w_h00, 'P') -DECLARE_OVERLAP_INSN(pmaccu_w_h01, 'P') -DECLARE_OVERLAP_INSN(pmaccu_w_h11, 'P') -DECLARE_OVERLAP_INSN(pmhacc_w, 'P') -DECLARE_OVERLAP_INSN(pmhacc_w_h0, 'P') -DECLARE_OVERLAP_INSN(pmhacc_w_h1, 'P') -DECLARE_OVERLAP_INSN(pmhaccsu_w, 'P') -DECLARE_OVERLAP_INSN(pmhaccsu_w_h0, 'P') -DECLARE_OVERLAP_INSN(pmhaccsu_w_h1, 'P') -DECLARE_OVERLAP_INSN(pmhaccu_w, 'P') -DECLARE_OVERLAP_INSN(pmhracc_w, 'P') -DECLARE_OVERLAP_INSN(pmhraccsu_w, 'P') -DECLARE_OVERLAP_INSN(pmhraccu_w, 'P') -DECLARE_OVERLAP_INSN(pmqacc_w_h00, 'P') -DECLARE_OVERLAP_INSN(pmqacc_w_h01, 'P') -DECLARE_OVERLAP_INSN(pmqacc_w_h11, 'P') -DECLARE_OVERLAP_INSN(pmqracc_w_h00, 'P') -DECLARE_OVERLAP_INSN(pmqracc_w_h01, 'P') -DECLARE_OVERLAP_INSN(pmqracc_w_h11, 'P') -DECLARE_OVERLAP_INSN(psshl_ws, 'P') -DECLARE_OVERLAP_INSN(psshlr_ws, 'P') +// rv64p overlap rv32p — register only on RV64 so the RV32 scalar mnemonic wins on RV32 +DECLARE_OVERLAP_INSN_RV64(paadd_w, 'P') +DECLARE_OVERLAP_INSN_RV64(paaddu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pasub_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pasubu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(psadd_w, 'P') +DECLARE_OVERLAP_INSN_RV64(psaddu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pssh1sadd_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pssub_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pssubu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(psati_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pusati_w, 'P') +DECLARE_OVERLAP_INSN_RV64(psrari_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pssha_ws, 'P') +DECLARE_OVERLAP_INSN_RV64(psshar_ws, 'P') +DECLARE_OVERLAP_INSN_RV64(psslai_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmseq_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmslt_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmsltu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmul_w_h00, 'P') +DECLARE_OVERLAP_INSN_RV64(pmul_w_h01, 'P') +DECLARE_OVERLAP_INSN_RV64(pmul_w_h11, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulh_w_h0, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulh_w_h1, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulhr_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulhrsu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulhru_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulhsu_w_h0, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulhsu_w_h1, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulq_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulqr_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulsu_w_h00, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulsu_w_h11, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulu_w_h00, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulu_w_h01, 'P') +DECLARE_OVERLAP_INSN_RV64(pmulu_w_h11, 'P') +DECLARE_OVERLAP_INSN_RV64(pmacc_w_h00, 'P') +DECLARE_OVERLAP_INSN_RV64(pmacc_w_h01, 'P') +DECLARE_OVERLAP_INSN_RV64(pmacc_w_h11, 'P') +DECLARE_OVERLAP_INSN_RV64(pmaccsu_w_h00, 'P') +DECLARE_OVERLAP_INSN_RV64(pmaccsu_w_h11, 'P') +DECLARE_OVERLAP_INSN_RV64(pmaccu_w_h00, 'P') +DECLARE_OVERLAP_INSN_RV64(pmaccu_w_h01, 'P') +DECLARE_OVERLAP_INSN_RV64(pmaccu_w_h11, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhacc_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhacc_w_h0, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhacc_w_h1, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhaccsu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhaccsu_w_h0, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhaccsu_w_h1, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhaccu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhracc_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhraccsu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmhraccu_w, 'P') +DECLARE_OVERLAP_INSN_RV64(pmqacc_w_h00, 'P') +DECLARE_OVERLAP_INSN_RV64(pmqacc_w_h01, 'P') +DECLARE_OVERLAP_INSN_RV64(pmqacc_w_h11, 'P') +DECLARE_OVERLAP_INSN_RV64(pmqracc_w_h00, 'P') +DECLARE_OVERLAP_INSN_RV64(pmqracc_w_h01, 'P') +DECLARE_OVERLAP_INSN_RV64(pmqracc_w_h11, 'P') +DECLARE_OVERLAP_INSN_RV64(psshl_ws, 'P') +DECLARE_OVERLAP_INSN_RV64(psshlr_ws, 'P') diff --git a/riscv/processor.cc b/riscv/processor.cc index 95ceb349..08e24da3 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -770,8 +770,13 @@ void processor_t::register_base_instructions() name##_overlapping = true; \ if (isa.extension_enabled(ext)) \ DEFINE_INSN_UNCOND(name); + #define DECLARE_OVERLAP_INSN_RV64(name, ext) \ + name##_overlapping = true; \ + if (isa.extension_enabled(ext) && xlen == 64) \ + DEFINE_INSN_UNCOND(name); #include "overlap_list.h" #undef DECLARE_OVERLAP_INSN + #undef DECLARE_OVERLAP_INSN_RV64 // add all other instructions. since they are non-overlapping, the order // does not affect correctness, but more frequent instructions should From 4caf3468b968e568257be80ded5118f1c4e2219a Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Tue, 19 May 2026 00:24:19 -0700 Subject: [PATCH 02/12] rvp: fix shift w/ or w/o saturation Signed-off-by: Chih-Min Chao --- riscv/insns/pssh1sadd_w.h | 2 +- riscv/insns/pssha_hs.h | 6 +++--- riscv/insns/pssha_ws.h | 4 ++-- riscv/insns/psshar_hs.h | 4 ++-- riscv/insns/psshar_ws.h | 2 +- riscv/insns/psshl_dhs.h | 13 +++++-------- riscv/insns/psshl_dws.h | 13 +++++-------- riscv/insns/psshl_hs.h | 13 +++++-------- riscv/insns/psshl_ws.h | 13 +++++-------- riscv/insns/psshlr_dhs.h | 16 +++++----------- riscv/insns/psshlr_dws.h | 16 +++++----------- riscv/insns/psshlr_hs.h | 16 +++++----------- riscv/insns/psshlr_ws.h | 16 +++++----------- riscv/insns/shl.h | 13 ++++--------- riscv/insns/shlr.h | 15 +++------------ riscv/insns/sshar.h | 19 +++++++++++-------- riscv/insns/sshl.h | 17 +++++++---------- riscv/insns/sshlr.h | 22 ++++++++-------------- 18 files changed, 82 insertions(+), 138 deletions(-) diff --git a/riscv/insns/pssh1sadd_w.h b/riscv/insns/pssh1sadd_w.h index a84c17b0..325be89e 100644 --- a/riscv/insns/pssh1sadd_w.h +++ b/riscv/insns/pssh1sadd_w.h @@ -1,5 +1,5 @@ require_rv64; P_RD_RS1_RS2_LOOP(32, 32, 32, { - p_rd = P_SAT(32, P_SAT(32, p_rs1 << 1) + p_rs2); + p_rd = P_SAT(32, P_SAT(32, (int64_t)p_rs1 << 1) + p_rs2); } ) diff --git a/riscv/insns/pssha_hs.h b/riscv/insns/pssha_hs.h index 6d3b9746..6fe871d3 100644 --- a/riscv/insns/pssha_hs.h +++ b/riscv/insns/pssha_hs.h @@ -3,11 +3,11 @@ P_RD_RS1_LOOP(16, 16, { if (p_rs1 == 0) p_rd = 0; else if (sshamt >= 16) { - p_rd = (p_rs1 & 0x8000) ? 0x8000 : 0x7fff; + p_rd = (p_rs1 & 0x8000) ? INT16_MIN : INT16_MAX; P.set_vxsat(); } else if (sshamt <= -16) - p_rd = (p_rs1 & 0x8000) ? 0xffff : 0; + p_rd = (p_rs1 & 0x8000) ? (int16_t)UINT16_MAX : 0; else p_rd = sshamt >= 0 ? P_SAT(16, sext32(p_rs1) << sshamt) : (p_rs1 >> -sshamt); -}) \ No newline at end of file +}) diff --git a/riscv/insns/pssha_ws.h b/riscv/insns/pssha_ws.h index 129079e2..e98311aa 100644 --- a/riscv/insns/pssha_ws.h +++ b/riscv/insns/pssha_ws.h @@ -4,11 +4,11 @@ P_RD_RS1_LOOP(32, 32, { if (p_rs1 == 0) p_rd = 0; else if (sshamt >= 32) { - p_rd = (p_rs1 & 0x80000000) ? 0x80000000 : 0x7fffffff; + p_rd = (p_rs1 & 0x80000000) ? INT32_MIN : INT32_MAX; P.set_vxsat(); } else if (sshamt <= -32) - p_rd = (p_rs1 & 0x80000000) ? 0xffffffff : 0; + p_rd = (p_rs1 & 0x80000000) ? (int32_t)UINT32_MAX : 0; else p_rd = sshamt >= 0 ? P_SAT(32, sext32(p_rs1) << sshamt) : (p_rs1 >> -sshamt); } diff --git a/riscv/insns/psshar_hs.h b/riscv/insns/psshar_hs.h index c23fa3bf..dffc6082 100644 --- a/riscv/insns/psshar_hs.h +++ b/riscv/insns/psshar_hs.h @@ -3,11 +3,11 @@ P_RD_RS1_LOOP(16, 16, { if (p_rs1 == 0) p_rd = 0; else if (sshamt >= 16) { - p_rd = (p_rs1 & 0x8000) ? 0x8000 : 0x7fff; + p_rd = (p_rs1 & 0x8000) ? INT16_MIN : INT16_MAX; P.set_vxsat(); } else if (sshamt <= -16) p_rd = 0; else p_rd = sshamt >= 0 ? P_SAT(16, sext32(p_rs1) << sshamt) : ((p_rs1 >> -sshamt) + ((p_rs1 >> (-sshamt - 1)) & 1)); -}) \ No newline at end of file +}) diff --git a/riscv/insns/psshar_ws.h b/riscv/insns/psshar_ws.h index 87e3aa4f..ad7f5af3 100644 --- a/riscv/insns/psshar_ws.h +++ b/riscv/insns/psshar_ws.h @@ -4,7 +4,7 @@ P_RD_RS1_LOOP(32, 32, { if (p_rs1 == 0) p_rd = 0; else if (sshamt >= 32) { - p_rd = (p_rs1 & 0x80000000) ? 0x80000000 : 0x7fffffff; + p_rd = (p_rs1 & 0x80000000) ? INT32_MIN : INT32_MAX; P.set_vxsat(); } else if (sshamt <= -32) diff --git a/riscv/insns/psshl_dhs.h b/riscv/insns/psshl_dhs.h index 9ea07474..f2821b80 100644 --- a/riscv/insns/psshl_dhs.h +++ b/riscv/insns/psshl_dhs.h @@ -1,16 +1,13 @@ require_rv32; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); P_RD_RS1_DW_LOOP(16, 16, { if (sshamt < 0) { - if (sshamt <= -16) - p_rd = 0; - else - p_rd = (uint16_t)p_rs1 >> (-sshamt); + p_rd = (uint32_t)(uint16_t)p_rs1 >> std::min(-sshamt, 16); } else { - uint32_t shx = (sshamt >= 16) ? ((uint32_t)(uint16_t)p_rs1 << 16) : ((uint32_t)(uint16_t)p_rs1 << sshamt); - if (shx > 0xFFFF) { + uint32_t shx = (uint32_t)(uint16_t)p_rs1 << std::min(sshamt, 16); + if (shx > UINT16_MAX) { P.set_vxsat(); - p_rd = 0xFFFF; + p_rd = (uint16_t)UINT16_MAX; } else { p_rd = (uint16_t)shx; } diff --git a/riscv/insns/psshl_dws.h b/riscv/insns/psshl_dws.h index 2b905db0..ca5a4b3d 100644 --- a/riscv/insns/psshl_dws.h +++ b/riscv/insns/psshl_dws.h @@ -1,16 +1,13 @@ require_rv32; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); P_RD_RS1_DW_LOOP(32, 32, { if (sshamt < 0) { - if (sshamt <= -32) - p_rd = 0; - else - p_rd = (uint32_t)p_rs1 >> (-sshamt); + p_rd = (uint64_t)(uint32_t)p_rs1 >> std::min(-sshamt, 32); } else { - uint64_t shx = (sshamt >= 32) ? ((uint64_t)(uint32_t)p_rs1 << 32) : ((uint64_t)(uint32_t)p_rs1 << sshamt); - if (shx > 0xFFFFFFFFULL) { + uint64_t shx = (uint64_t)(uint32_t)p_rs1 << std::min(sshamt, 32); + if (shx > UINT32_MAX) { P.set_vxsat(); - p_rd = 0xFFFFFFFF; + p_rd = UINT32_MAX; } else { p_rd = (uint32_t)shx; } diff --git a/riscv/insns/psshl_hs.h b/riscv/insns/psshl_hs.h index 291c727c..17e6192e 100644 --- a/riscv/insns/psshl_hs.h +++ b/riscv/insns/psshl_hs.h @@ -1,15 +1,12 @@ -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); P_RD_RS1_LOOP(16, 16, { if (sshamt < 0) { - if (sshamt <= -16) - p_rd = 0; - else - p_rd = (uint16_t)p_rs1 >> (-sshamt); + p_rd = (uint32_t)(uint16_t)p_rs1 >> std::min(-sshamt, 16); } else { - uint32_t shx = (sshamt >= 16) ? ((uint32_t)(uint16_t)p_rs1 << 16) : ((uint32_t)(uint16_t)p_rs1 << sshamt); - if (shx > 0xFFFF) { + uint32_t shx = (uint32_t)(uint16_t)p_rs1 << std::min(sshamt, 16); + if (shx > UINT16_MAX) { P.set_vxsat(); - p_rd = 0xFFFF; + p_rd = (uint16_t)UINT16_MAX; } else { p_rd = (uint16_t)shx; } diff --git a/riscv/insns/psshl_ws.h b/riscv/insns/psshl_ws.h index 483cec71..69422611 100644 --- a/riscv/insns/psshl_ws.h +++ b/riscv/insns/psshl_ws.h @@ -1,16 +1,13 @@ require_rv64; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); P_RD_RS1_LOOP(32, 32, { if (sshamt < 0) { - if (sshamt <= -32) - p_rd = 0; - else - p_rd = (uint32_t)p_rs1 >> (-sshamt); + p_rd = (uint64_t)(uint32_t)p_rs1 >> std::min(-sshamt, 32); } else { - uint64_t shx = (sshamt >= 32) ? ((uint64_t)(uint32_t)p_rs1 << 32) : ((uint64_t)(uint32_t)p_rs1 << sshamt); - if (shx > 0xFFFFFFFFULL) { + uint64_t shx = (uint64_t)(uint32_t)p_rs1 << std::min(sshamt, 32); + if (shx > UINT32_MAX) { P.set_vxsat(); - p_rd = 0xFFFFFFFF; + p_rd = UINT32_MAX; } else { p_rd = (uint32_t)shx; } diff --git a/riscv/insns/psshlr_dhs.h b/riscv/insns/psshlr_dhs.h index f61d4a63..7c9b39bb 100644 --- a/riscv/insns/psshlr_dhs.h +++ b/riscv/insns/psshlr_dhs.h @@ -1,20 +1,14 @@ require_rv32; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); P_RD_RS1_DW_LOOP(16, 16, { if (sshamt < 0) { - uint32_t shx; - if (sshamt < -16) - shx = 0; - else if (sshamt == -16) - shx = ((uint16_t)p_rs1 >> 15) & 1; - else - shx = ((uint32_t)(uint16_t)p_rs1 << 1) >> (-sshamt); + uint32_t shx = ((uint32_t)(uint16_t)p_rs1 << 1) >> std::min(-sshamt, 16); p_rd = (uint16_t)((shx + 1) >> 1); } else { - uint32_t shx = (sshamt >= 16) ? ((uint32_t)(uint16_t)p_rs1 << 16) : ((uint32_t)(uint16_t)p_rs1 << sshamt); - if (shx > 0xFFFF) { + uint32_t shx = (uint32_t)(uint16_t)p_rs1 << std::min(sshamt, 16); + if (shx > UINT16_MAX) { P.set_vxsat(); - p_rd = 0xFFFF; + p_rd = (uint16_t)UINT16_MAX; } else { p_rd = (uint16_t)shx; } diff --git a/riscv/insns/psshlr_dws.h b/riscv/insns/psshlr_dws.h index 60b0e2dd..380ea40e 100644 --- a/riscv/insns/psshlr_dws.h +++ b/riscv/insns/psshlr_dws.h @@ -1,20 +1,14 @@ require_rv32; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); P_RD_RS1_DW_LOOP(32, 32, { if (sshamt < 0) { - uint64_t shx; - if (sshamt < -32) - shx = 0; - else if (sshamt == -32) - shx = ((uint32_t)p_rs1 >> 31) & 1; - else - shx = ((uint64_t)(uint32_t)p_rs1 << 1) >> (-sshamt); + uint64_t shx = ((uint64_t)(uint32_t)p_rs1 << 1) >> std::min(-sshamt, 32); p_rd = (uint32_t)((shx + 1) >> 1); } else { - uint64_t shx = (sshamt >= 32) ? ((uint64_t)(uint32_t)p_rs1 << 32) : ((uint64_t)(uint32_t)p_rs1 << sshamt); - if (shx > 0xFFFFFFFFULL) { + uint64_t shx = (uint64_t)(uint32_t)p_rs1 << std::min(sshamt, 32); + if (shx > UINT32_MAX) { P.set_vxsat(); - p_rd = 0xFFFFFFFF; + p_rd = UINT32_MAX; } else { p_rd = (uint32_t)shx; } diff --git a/riscv/insns/psshlr_hs.h b/riscv/insns/psshlr_hs.h index 9573dc79..08c859be 100644 --- a/riscv/insns/psshlr_hs.h +++ b/riscv/insns/psshlr_hs.h @@ -1,19 +1,13 @@ -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); P_RD_RS1_LOOP(16, 16, { if (sshamt < 0) { - uint32_t shx; - if (sshamt < -16) - shx = 0; - else if (sshamt == -16) - shx = ((uint16_t)p_rs1 >> 15) & 1; - else - shx = ((uint32_t)(uint16_t)p_rs1 << 1) >> (-sshamt); + uint32_t shx = ((uint32_t)(uint16_t)p_rs1 << 1) >> std::min(-sshamt, 16); p_rd = (uint16_t)((shx + 1) >> 1); } else { - uint32_t shx = (sshamt >= 16) ? ((uint32_t)(uint16_t)p_rs1 << 16) : ((uint32_t)(uint16_t)p_rs1 << sshamt); - if (shx > 0xFFFF) { + uint32_t shx = (uint32_t)(uint16_t)p_rs1 << std::min(sshamt, 16); + if (shx > UINT16_MAX) { P.set_vxsat(); - p_rd = 0xFFFF; + p_rd = (uint16_t)UINT16_MAX; } else { p_rd = (uint16_t)shx; } diff --git a/riscv/insns/psshlr_ws.h b/riscv/insns/psshlr_ws.h index de832f56..895ad00e 100644 --- a/riscv/insns/psshlr_ws.h +++ b/riscv/insns/psshlr_ws.h @@ -1,20 +1,14 @@ require_rv64; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); P_RD_RS1_LOOP(32, 32, { if (sshamt < 0) { - uint64_t shx; - if (sshamt < -32) - shx = 0; - else if (sshamt == -32) - shx = ((uint32_t)p_rs1 >> 31) & 1; - else - shx = ((uint64_t)(uint32_t)p_rs1 << 1) >> (-sshamt); + uint64_t shx = ((uint64_t)(uint32_t)p_rs1 << 1) >> std::min(-sshamt, 32); p_rd = (uint32_t)((shx + 1) >> 1); } else { - uint64_t shx = (sshamt >= 32) ? ((uint64_t)(uint32_t)p_rs1 << 32) : ((uint64_t)(uint32_t)p_rs1 << sshamt); - if (shx > 0xFFFFFFFFULL) { + uint64_t shx = (uint64_t)(uint32_t)p_rs1 << std::min(sshamt, 32); + if (shx > UINT32_MAX) { P.set_vxsat(); - p_rd = 0xFFFFFFFF; + p_rd = UINT32_MAX; } else { p_rd = (uint32_t)shx; } diff --git a/riscv/insns/shl.h b/riscv/insns/shl.h index ef112422..171f31c3 100644 --- a/riscv/insns/shl.h +++ b/riscv/insns/shl.h @@ -1,15 +1,10 @@ require_extension('P'); require_rv64; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); +uint128_t shx = RS1; if (sshamt < 0) { - if (sshamt <= -64) - WRITE_RD(0); - else - WRITE_RD(RS1 >> (-sshamt)); + WRITE_RD(shx >> std::min(-sshamt, 64)); } else { - if (sshamt >= 64) - WRITE_RD(0); - else - WRITE_RD(RS1 << sshamt); + WRITE_RD(shx << std::min(sshamt, 64)); } diff --git a/riscv/insns/shlr.h b/riscv/insns/shlr.h index 29801fa9..7ebce992 100644 --- a/riscv/insns/shlr.h +++ b/riscv/insns/shlr.h @@ -1,19 +1,10 @@ require_extension('P'); require_rv64; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); if (sshamt < 0) { - __uint128_t shx; - if (sshamt < -64) - shx = 0; - else if (sshamt == -64) - shx = (RS1 >> 63) & 1; - else - shx = ((__uint128_t)RS1 << 1) >> (-sshamt); + uint128_t shx = ((uint128_t)RS1 << 1) >> std::min(-sshamt, 64); WRITE_RD((uint64_t)((shx + 1) >> 1)); } else { - if (sshamt >= 64) - WRITE_RD(0); - else - WRITE_RD(RS1 << sshamt); + WRITE_RD((uint128_t)RS1 << std::min(sshamt, 64)); } diff --git a/riscv/insns/sshar.h b/riscv/insns/sshar.h index c902ab3a..3a8b3b07 100644 --- a/riscv/insns/sshar.h +++ b/riscv/insns/sshar.h @@ -1,13 +1,16 @@ require_extension('P'); require_rv32; sreg_t sshamt = P_FIELD(RS2, 0, 8); -if (RS1 == 0) - WRITE_RD(0); -else if (sshamt >= 32) { - WRITE_RD((RS1 & 0x80000000) ? 0x80000000 : 0x7fffffff); +sreg_t val; +if (RS1 == 0) { + val = 0; +} else if (sshamt >= 32) { + val = (RS1 & 0x80000000) ? 0x80000000 : 0x7fffffff; P.set_vxsat(); +} else if (sshamt <= -32) { + val = 0; +} else { + val = sshamt >= 0 ? P_SAT(32, static_cast (RS1) << sshamt) : ((RS1 >> -sshamt) + ((RS1 >> (-sshamt - 1)) & 1)); } -else if (sshamt <= -32) - WRITE_RD(0); -else - WRITE_RD(sshamt >= 0 ? P_SAT(32, static_cast (RS1) << sshamt) : ((RS1 >> -sshamt) + ((RS1 >> (-sshamt - 1)) & 1))); \ No newline at end of file + +WRITE_RD(sext32(val)); diff --git a/riscv/insns/sshl.h b/riscv/insns/sshl.h index 8d3d473a..68cb4b80 100644 --- a/riscv/insns/sshl.h +++ b/riscv/insns/sshl.h @@ -1,18 +1,15 @@ require_extension('P'); require_rv32; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); +uint64_t shx; if (sshamt < 0) { - if (sshamt <= -32) - WRITE_RD(0); - else - WRITE_RD(RS1 >> (-sshamt)); + shx = ((uint64_t)(uint32_t)RS1) >> std::min(-sshamt, 32); } else { - uint64_t shx = (sshamt >= 32) ? ((uint64_t)RS1 << 32) : ((uint64_t)RS1 << sshamt); - if (shx > 0xFFFFFFFFULL) { + shx = (uint64_t)RS1 << std::min(sshamt, 32); + if (shx > UINT32_MAX) { P.set_vxsat(); - WRITE_RD(0xFFFFFFFF); - } else { - WRITE_RD((uint32_t)shx); + shx = UINT32_MAX; } } +WRITE_RD(sext32(shx)); diff --git a/riscv/insns/sshlr.h b/riscv/insns/sshlr.h index 06f8e15d..9738f88d 100644 --- a/riscv/insns/sshlr.h +++ b/riscv/insns/sshlr.h @@ -1,22 +1,16 @@ require_extension('P'); require_rv32; -sreg_t sshamt = P_FIELD(RS2, 0, 8); +int sshamt = P_FIELD(RS2, 0, 8); +uint64_t shx; if (sshamt < 0) { - uint64_t shx; - if (sshamt < -32) - shx = 0; - else if (sshamt == -32) - shx = (RS1 >> 31) & 1; - else - shx = ((uint64_t)RS1 << 1) >> (-sshamt); - WRITE_RD((uint32_t)((shx + 1) >> 1)); + shx = ((uint64_t)(uint32_t)RS1 << 1) >> std::min(-sshamt, 32); + shx = (shx + 1) >> 1; } else { - uint64_t shx = (sshamt >= 32) ? ((uint64_t)RS1 << 32) : ((uint64_t)RS1 << sshamt); - if (shx > 0xFFFFFFFFULL) { + shx = (uint64_t)RS1 << std::min(sshamt, 32); + if (shx > UINT32_MAX) { P.set_vxsat(); - WRITE_RD(0xFFFFFFFF); - } else { - WRITE_RD((uint32_t)shx); + shx = UINT32_MAX; } } +WRITE_RD(sext32(shx)); From 72a5c14248648c5e953e32529aa1b5b71246d238 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Tue, 19 May 2026 19:32:16 -0700 Subject: [PATCH 03/12] rvp: fix the result extraction of multiplication Signed-off-by: Chih-Min Chao --- riscv/insns/pmhacc_h.h | 4 ++-- riscv/insns/pmhacc_h_b0.h | 4 ++-- riscv/insns/pmhacc_h_b1.h | 4 ++-- riscv/insns/pmhacc_w_h0.h | 2 +- riscv/insns/pmhacc_w_h1.h | 2 +- riscv/insns/pmhaccsu_h_b0.h | 4 ++-- riscv/insns/pmhaccsu_h_b1.h | 4 ++-- riscv/insns/pmhaccsu_w_h0.h | 2 +- riscv/insns/pmhaccsu_w_h1.h | 2 +- riscv/insns/pmulh_h_b0.h | 4 ++-- riscv/insns/pmulh_h_b1.h | 4 ++-- riscv/insns/pmulh_w_h0.h | 2 +- riscv/insns/pmulh_w_h1.h | 2 +- riscv/insns/pmulhsu_h_b0.h | 4 ++-- riscv/insns/pmulhsu_h_b1.h | 4 ++-- riscv/insns/pmulhsu_w_h1.h | 2 +- 16 files changed, 25 insertions(+), 25 deletions(-) diff --git a/riscv/insns/pmhacc_h.h b/riscv/insns/pmhacc_h.h index 053c2858..b50bb7ae 100644 --- a/riscv/insns/pmhacc_h.h +++ b/riscv/insns/pmhacc_h.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_LOOP(16,16,16, { int32_t mres = sext32(p_rs1) * sext32(p_rs2); - p_rd += mres>>16; -}) \ No newline at end of file + p_rd += mres>>16; +}) diff --git a/riscv/insns/pmhacc_h_b0.h b/riscv/insns/pmhacc_h_b0.h index 60a1d5c2..922fcb3b 100644 --- a/riscv/insns/pmhacc_h_b0.h +++ b/riscv/insns/pmhacc_h_b0.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_E_LOOP(16,16,8, { int32_t mres = sext32(p_rs1) * sext32(p_rs2); - p_rd += mres>>16; -}) \ No newline at end of file + p_rd += mres>>8; +}) diff --git a/riscv/insns/pmhacc_h_b1.h b/riscv/insns/pmhacc_h_b1.h index c7aa4d7a..1ce9863b 100644 --- a/riscv/insns/pmhacc_h_b1.h +++ b/riscv/insns/pmhacc_h_b1.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_O_LOOP(16,16,8, { int32_t mres = sext32(p_rs1) * sext32(p_rs2); - p_rd += mres>>16; -}) \ No newline at end of file + p_rd += mres>>8; +}) diff --git a/riscv/insns/pmhacc_w_h0.h b/riscv/insns/pmhacc_w_h0.h index 76b33778..5e2d8434 100644 --- a/riscv/insns/pmhacc_w_h0.h +++ b/riscv/insns/pmhacc_w_h0.h @@ -1,6 +1,6 @@ require_rv64; P_RD_RS1_RS2_E_LOOP(32,32,16, { sreg_t mres = sext(p_rs1,64) * sext(p_rs2,64); - p_rd += mres>>32; + p_rd += mres>>16; } ) diff --git a/riscv/insns/pmhacc_w_h1.h b/riscv/insns/pmhacc_w_h1.h index 9f103ad6..95b022f6 100644 --- a/riscv/insns/pmhacc_w_h1.h +++ b/riscv/insns/pmhacc_w_h1.h @@ -1,6 +1,6 @@ require_rv64; P_RD_RS1_RS2_O_LOOP(32,32,16, { sreg_t mres = sext(p_rs1,64) * sext(p_rs2,64); - p_rd += mres>>32; + p_rd += mres>>16; } ) diff --git a/riscv/insns/pmhaccsu_h_b0.h b/riscv/insns/pmhaccsu_h_b0.h index 3d14229b..85c261ad 100644 --- a/riscv/insns/pmhaccsu_h_b0.h +++ b/riscv/insns/pmhaccsu_h_b0.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_E_SULOOP(16,16,8, { int32_t mres = sext(p_rs1,32) * zext(p_rs2,32); - p_rd += mres>>16; -}) \ No newline at end of file + p_rd += mres>>8; +}) diff --git a/riscv/insns/pmhaccsu_h_b1.h b/riscv/insns/pmhaccsu_h_b1.h index 6a5a478f..9b6453a5 100644 --- a/riscv/insns/pmhaccsu_h_b1.h +++ b/riscv/insns/pmhaccsu_h_b1.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_O_SULOOP(16,16,8, { int32_t mres = sext(p_rs1,32) * zext(p_rs2,32); - p_rd += mres>>16; -}) \ No newline at end of file + p_rd += mres>>8; +}) diff --git a/riscv/insns/pmhaccsu_w_h0.h b/riscv/insns/pmhaccsu_w_h0.h index 400eaa92..27189cd6 100644 --- a/riscv/insns/pmhaccsu_w_h0.h +++ b/riscv/insns/pmhaccsu_w_h0.h @@ -1,6 +1,6 @@ require_rv64; P_RD_RS1_RS2_E_SULOOP(32,32,16, { sreg_t mres = sext(p_rs1,64) * zext(p_rs2,64); - p_rd += mres>>32; + p_rd += mres>>16; } ) diff --git a/riscv/insns/pmhaccsu_w_h1.h b/riscv/insns/pmhaccsu_w_h1.h index 55b07f20..80794d4a 100644 --- a/riscv/insns/pmhaccsu_w_h1.h +++ b/riscv/insns/pmhaccsu_w_h1.h @@ -1,6 +1,6 @@ require_rv64; P_RD_RS1_RS2_O_SULOOP(32,32,16, { sreg_t mres = sext(p_rs1,64) * zext(p_rs2,64); - p_rd += mres>>32; + p_rd += mres>>16; } ) diff --git a/riscv/insns/pmulh_h_b0.h b/riscv/insns/pmulh_h_b0.h index 5c69a9c6..141fd704 100644 --- a/riscv/insns/pmulh_h_b0.h +++ b/riscv/insns/pmulh_h_b0.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_E_LOOP(16,16,8, { int32_t mres = sext(p_rs1,32) * sext(p_rs2,32); - p_rd = mres >> 16; -}) \ No newline at end of file + p_rd = mres >> 8; +}) diff --git a/riscv/insns/pmulh_h_b1.h b/riscv/insns/pmulh_h_b1.h index 1cd5d680..caa411e4 100644 --- a/riscv/insns/pmulh_h_b1.h +++ b/riscv/insns/pmulh_h_b1.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_O_LOOP(16,16,8, { int32_t mres = sext(p_rs1,32) * sext(p_rs2,32); - p_rd = mres >> 16; -}) \ No newline at end of file + p_rd = mres >> 8; +}) diff --git a/riscv/insns/pmulh_w_h0.h b/riscv/insns/pmulh_w_h0.h index bff17442..eb31f71b 100644 --- a/riscv/insns/pmulh_w_h0.h +++ b/riscv/insns/pmulh_w_h0.h @@ -1,6 +1,6 @@ require_rv64; P_RD_RS1_RS2_E_LOOP(32,32,16, { sreg_t mres = sext(p_rs1,64) * sext(p_rs2,64); - p_rd = mres >> 32; + p_rd = mres >> 16; } ) diff --git a/riscv/insns/pmulh_w_h1.h b/riscv/insns/pmulh_w_h1.h index 3a62a4aa..d8246a7b 100644 --- a/riscv/insns/pmulh_w_h1.h +++ b/riscv/insns/pmulh_w_h1.h @@ -1,6 +1,6 @@ require_rv64; P_RD_RS1_RS2_O_LOOP(32,32,16, { sreg_t mres = sext(p_rs1,64) * sext(p_rs2,64); - p_rd = mres >> 32; + p_rd = mres >> 16; } ) diff --git a/riscv/insns/pmulhsu_h_b0.h b/riscv/insns/pmulhsu_h_b0.h index 3cfdd4b4..a18aafd3 100644 --- a/riscv/insns/pmulhsu_h_b0.h +++ b/riscv/insns/pmulhsu_h_b0.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_E_SULOOP(16,16,8, { int32_t mres = sext(p_rs1,32) * zext(p_rs2,32); - p_rd = mres >> 16; -}) \ No newline at end of file + p_rd = mres >> 8; +}) diff --git a/riscv/insns/pmulhsu_h_b1.h b/riscv/insns/pmulhsu_h_b1.h index 4e6b5bf3..026e5278 100644 --- a/riscv/insns/pmulhsu_h_b1.h +++ b/riscv/insns/pmulhsu_h_b1.h @@ -1,4 +1,4 @@ P_RD_RS1_RS2_O_SULOOP(16,16,8, { int32_t mres = sext(p_rs1,32) * zext(p_rs2,32); - p_rd = mres >> 16; -}) \ No newline at end of file + p_rd = mres >> 8; +}) diff --git a/riscv/insns/pmulhsu_w_h1.h b/riscv/insns/pmulhsu_w_h1.h index fd5f2345..97d11480 100644 --- a/riscv/insns/pmulhsu_w_h1.h +++ b/riscv/insns/pmulhsu_w_h1.h @@ -1,6 +1,6 @@ require_rv64; P_RD_RS1_RS2_O_SULOOP(32,32,16, { sreg_t mres = sext(p_rs1,64) * zext(p_rs2,64); - p_rd = mres >> 32; + p_rd = mres >> 16; } ) From 8b1ad630880b2f4d9813179822b02faa57375bc1 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Tue, 19 May 2026 23:56:18 -0700 Subject: [PATCH 04/12] rvp: do sext32 before writing to rd for rv32 Signed-off-by: Chih-Min Chao --- riscv/insns/aadd.h | 2 +- riscv/insns/aaddu.h | 2 +- riscv/insns/asub.h | 2 +- riscv/insns/asubu.h | 2 +- riscv/insns/mqacc_h00.h | 2 +- riscv/insns/mqacc_h01.h | 2 +- riscv/insns/mqacc_h11.h | 2 +- riscv/insns/mqracc_h00.h | 2 +- riscv/insns/mqracc_h01.h | 2 +- riscv/insns/mqracc_h11.h | 2 +- riscv/insns/mulh_h0.h | 2 +- riscv/insns/mulh_h1.h | 2 +- riscv/insns/mulhsu_h0.h | 2 +- riscv/insns/mulhsu_h1.h | 2 +- riscv/insns/mulq.h | 2 +- riscv/insns/mulqr.h | 2 +- riscv/insns/nsra.h | 2 +- riscv/insns/nsrai.h | 2 +- riscv/insns/nsrar.h | 6 +++--- riscv/insns/nsrari.h | 6 +++--- riscv/insns/nsrl.h | 2 +- riscv/insns/nsrli.h | 2 +- riscv/insns/sadd.h | 2 +- riscv/insns/saddu.h | 5 ++++- riscv/insns/ssh1sadd.h | 2 +- riscv/insns/ssha.h | 19 +++++++++++-------- 26 files changed, 43 insertions(+), 37 deletions(-) diff --git a/riscv/insns/aadd.h b/riscv/insns/aadd.h index 5456cef6..21623553 100644 --- a/riscv/insns/aadd.h +++ b/riscv/insns/aadd.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD((RS1 + RS2)>>1); \ No newline at end of file +WRITE_RD(sext32((RS1 + RS2)>>1)); diff --git a/riscv/insns/aaddu.h b/riscv/insns/aaddu.h index bf011496..d799e4a1 100644 --- a/riscv/insns/aaddu.h +++ b/riscv/insns/aaddu.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD((0ULL + (uint32_t)RS1 + (uint32_t)RS2)>>1); \ No newline at end of file +WRITE_RD(sext32((0ULL + (uint32_t)RS1 + (uint32_t)RS2)>>1)); diff --git a/riscv/insns/asub.h b/riscv/insns/asub.h index b7a7ab53..b8a4a112 100644 --- a/riscv/insns/asub.h +++ b/riscv/insns/asub.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD((RS1 - RS2)>>1); \ No newline at end of file +WRITE_RD(sext32((RS1 - RS2)>>1)); diff --git a/riscv/insns/asubu.h b/riscv/insns/asubu.h index 6139feb2..4072c59c 100644 --- a/riscv/insns/asubu.h +++ b/riscv/insns/asubu.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD((0ULL + (uint32_t)RS1 - (uint32_t)RS2)>>1); \ No newline at end of file +WRITE_RD((sext32(0ULL + (uint32_t)RS1 - (uint32_t)RS2)>>1)); diff --git a/riscv/insns/mqacc_h00.h b/riscv/insns/mqacc_h00.h index 7b4b8e7c..7a586419 100644 --- a/riscv/insns/mqacc_h00.h +++ b/riscv/insns/mqacc_h00.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(RD + (((int32_t)P_FIELD(RS1, 0, 16) * P_FIELD(RS2, 0, 16)) >> 15)); \ No newline at end of file +WRITE_RD(sext32(RD + (((int32_t)P_FIELD(RS1, 0, 16) * P_FIELD(RS2, 0, 16)) >> 15))); diff --git a/riscv/insns/mqacc_h01.h b/riscv/insns/mqacc_h01.h index ff618720..e03f2804 100644 --- a/riscv/insns/mqacc_h01.h +++ b/riscv/insns/mqacc_h01.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(RD + (((int32_t)P_FIELD(RS1, 0, 16) * P_FIELD(RS2, 1, 16)) >> 15)); \ No newline at end of file +WRITE_RD(sext32(RD + (((int32_t)P_FIELD(RS1, 0, 16) * P_FIELD(RS2, 1, 16)) >> 15))); diff --git a/riscv/insns/mqacc_h11.h b/riscv/insns/mqacc_h11.h index ac9e18bc..cb1b55f8 100644 --- a/riscv/insns/mqacc_h11.h +++ b/riscv/insns/mqacc_h11.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(RD + (((int32_t)P_FIELD(RS1, 1, 16) * P_FIELD(RS2, 1, 16)) >> 15)); \ No newline at end of file +WRITE_RD(sext32(RD + (((int32_t)P_FIELD(RS1, 1, 16) * P_FIELD(RS2, 1, 16)) >> 15))); diff --git a/riscv/insns/mqracc_h00.h b/riscv/insns/mqracc_h00.h index 37d49bde..3dd97054 100644 --- a/riscv/insns/mqracc_h00.h +++ b/riscv/insns/mqracc_h00.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(RD + (((int32_t)P_FIELD(RS1, 0, 16) * P_FIELD(RS2, 0, 16) + 0x4000) >> 15)); \ No newline at end of file +WRITE_RD(sext32(RD + (((int32_t)P_FIELD(RS1, 0, 16) * P_FIELD(RS2, 0, 16) + 0x4000) >> 15))); diff --git a/riscv/insns/mqracc_h01.h b/riscv/insns/mqracc_h01.h index 3e7358e5..86024b0d 100644 --- a/riscv/insns/mqracc_h01.h +++ b/riscv/insns/mqracc_h01.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(RD + (((int32_t)P_FIELD(RS1, 0, 16) * P_FIELD(RS2, 1, 16) + 0x4000) >> 15)); \ No newline at end of file +WRITE_RD(sext32(RD + (((int32_t)P_FIELD(RS1, 0, 16) * P_FIELD(RS2, 1, 16) + 0x4000) >> 15))); diff --git a/riscv/insns/mqracc_h11.h b/riscv/insns/mqracc_h11.h index c4eb4860..736f4b7f 100644 --- a/riscv/insns/mqracc_h11.h +++ b/riscv/insns/mqracc_h11.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(RD + (((int32_t)P_FIELD(RS1, 1, 16) * P_FIELD(RS2, 1, 16) + 0x4000) >> 15)); \ No newline at end of file +WRITE_RD(sext32(RD + (((int32_t)P_FIELD(RS1, 1, 16) * P_FIELD(RS2, 1, 16) + 0x4000) >> 15))); diff --git a/riscv/insns/mulh_h0.h b/riscv/insns/mulh_h0.h index 2143d3d2..543abbfe 100644 --- a/riscv/insns/mulh_h0.h +++ b/riscv/insns/mulh_h0.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; int64_t mres = sext(RS1,64) * sext(P_FIELD(RS2, 0, 16),64); -WRITE_RD(mres>>32); \ No newline at end of file +WRITE_RD(sext32(mres>>16)); diff --git a/riscv/insns/mulh_h1.h b/riscv/insns/mulh_h1.h index 5e5bf994..49738135 100644 --- a/riscv/insns/mulh_h1.h +++ b/riscv/insns/mulh_h1.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; int64_t mres = sext(RS1,64) * sext(P_FIELD(RS2, 1, 16),64); -WRITE_RD(mres>>32); \ No newline at end of file +WRITE_RD(sext32(mres>>16)); diff --git a/riscv/insns/mulhsu_h0.h b/riscv/insns/mulhsu_h0.h index 2cdb292c..6040d4fd 100644 --- a/riscv/insns/mulhsu_h0.h +++ b/riscv/insns/mulhsu_h0.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * (uint32_t)P_FIELD(RS2, 0, 16); -WRITE_RD(mres >> 32); \ No newline at end of file +WRITE_RD(sext32(mres >> 16)); diff --git a/riscv/insns/mulhsu_h1.h b/riscv/insns/mulhsu_h1.h index 4cc9fc32..94697ad6 100644 --- a/riscv/insns/mulhsu_h1.h +++ b/riscv/insns/mulhsu_h1.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * (uint32_t)P_FIELD(RS2, 1, 16); -WRITE_RD(mres >> 32); \ No newline at end of file +WRITE_RD(sext32(mres >> 16)); diff --git a/riscv/insns/mulq.h b/riscv/insns/mulq.h index 22c76e54..168f2a17 100644 --- a/riscv/insns/mulq.h +++ b/riscv/insns/mulq.h @@ -1,7 +1,7 @@ require_extension('P'); require_rv32; if ((RS1 != (reg_t)INT32_MIN) || (RS2 != (reg_t)INT32_MIN)) { - WRITE_RD((RS1 * RS2) >> 31); + WRITE_RD(sext32((RS1 * RS2) >> 31)); } else { WRITE_RD(INT32_MAX); P.set_vxsat(); diff --git a/riscv/insns/mulqr.h b/riscv/insns/mulqr.h index ca40fc57..1a7671d2 100644 --- a/riscv/insns/mulqr.h +++ b/riscv/insns/mulqr.h @@ -1,7 +1,7 @@ require_extension('P'); require_rv32; if ((RS1 != (reg_t)INT32_MIN) || (RS2 != (reg_t)INT32_MIN)) { - WRITE_RD((((RS1 * RS2) >> 30) + 1) >> 1); + WRITE_RD(sext32((((RS1 * RS2) >> 30) + 1) >> 1)); } else { WRITE_RD(INT32_MAX); P.set_vxsat(); diff --git a/riscv/insns/nsra.h b/riscv/insns/nsra.h index 7cf9f39f..219c18a3 100644 --- a/riscv/insns/nsra.h +++ b/riscv/insns/nsra.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD((sreg_t)P_RS1_PAIR >> (RS2 & 0x3f)); \ No newline at end of file +WRITE_RD(sext32((sreg_t)P_RS1_PAIR >> (RS2 & 0x3f))); diff --git a/riscv/insns/nsrai.h b/riscv/insns/nsrai.h index 63e287ca..188b2d5a 100644 --- a/riscv/insns/nsrai.h +++ b/riscv/insns/nsrai.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD((sreg_t)P_RS1_PAIR >> insn.shamtd()); \ No newline at end of file +WRITE_RD(sext32((sreg_t)P_RS1_PAIR >> insn.shamtd())); diff --git a/riscv/insns/nsrar.h b/riscv/insns/nsrar.h index b0879d3f..bbbf3267 100644 --- a/riscv/insns/nsrar.h +++ b/riscv/insns/nsrar.h @@ -4,8 +4,8 @@ sreg_t val = (sreg_t)P_RS1_PAIR; uint32_t shamt = RS2 & 0x3f; sreg_t result; if (shamt == 0) { - result = val; + result = val; } else { - result = (val >> shamt) + ((val >> (shamt - 1)) & 1); + result = (val >> shamt) + ((val >> (shamt - 1)) & 1); } -WRITE_RD(result); +WRITE_RD(sext32(result)); diff --git a/riscv/insns/nsrari.h b/riscv/insns/nsrari.h index 4e5fb806..187f48e9 100644 --- a/riscv/insns/nsrari.h +++ b/riscv/insns/nsrari.h @@ -4,8 +4,8 @@ sreg_t val = (sreg_t)P_RS1_PAIR; uint32_t shamt = insn.shamtd(); sreg_t result; if (shamt == 0) { - result = val; + result = val; } else { - result = (val >> shamt) + ((val >> (shamt - 1)) & 1); + result = (val >> shamt) + ((val >> (shamt - 1)) & 1); } -WRITE_RD(result); +WRITE_RD(sext32(result)); diff --git a/riscv/insns/nsrl.h b/riscv/insns/nsrl.h index 7de7e5b8..7c6bce9d 100644 --- a/riscv/insns/nsrl.h +++ b/riscv/insns/nsrl.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(P_RS1_PAIR >> (RS2 & 0x3f)); \ No newline at end of file +WRITE_RD(sext32(P_RS1_PAIR >> (RS2 & 0x3f))); diff --git a/riscv/insns/nsrli.h b/riscv/insns/nsrli.h index b85a84ee..e225a1e9 100644 --- a/riscv/insns/nsrli.h +++ b/riscv/insns/nsrli.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(P_RS1_PAIR >> insn.shamtd()); \ No newline at end of file +WRITE_RD(sext32(P_RS1_PAIR >> insn.shamtd())); diff --git a/riscv/insns/sadd.h b/riscv/insns/sadd.h index 94cc264c..38214da5 100644 --- a/riscv/insns/sadd.h +++ b/riscv/insns/sadd.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(P_SAT(xlen, sext_xlen((RS1 << 1) + RS2))); \ No newline at end of file +WRITE_RD(sext32(P_SAT(xlen, (RS1 + RS2)))); diff --git a/riscv/insns/saddu.h b/riscv/insns/saddu.h index dec16b84..3128bc28 100644 --- a/riscv/insns/saddu.h +++ b/riscv/insns/saddu.h @@ -1,4 +1,7 @@ require_extension('P'); require_rv32; bool sat = false; -WRITE_RD(sat_addu(RS1, RS2, sat)); \ No newline at end of file +reg_t tmp = sat_addu(RS1, RS2, sat); +if (sat) + P.set_vxsat(); +WRITE_RD(sext32(tmp)); diff --git a/riscv/insns/ssh1sadd.h b/riscv/insns/ssh1sadd.h index 94cc264c..c8223934 100644 --- a/riscv/insns/ssh1sadd.h +++ b/riscv/insns/ssh1sadd.h @@ -1,3 +1,3 @@ require_extension('P'); require_rv32; -WRITE_RD(P_SAT(xlen, sext_xlen((RS1 << 1) + RS2))); \ No newline at end of file +WRITE_RD(sext32(P_SAT(xlen, ((RS1 << 1) + RS2)))); diff --git a/riscv/insns/ssha.h b/riscv/insns/ssha.h index c247ffcf..b7509e05 100644 --- a/riscv/insns/ssha.h +++ b/riscv/insns/ssha.h @@ -1,13 +1,16 @@ require_extension('P'); require_rv32; sreg_t sshamt = P_FIELD(RS2, 0, 8); -if (RS1 == 0) - WRITE_RD(0); -else if (sshamt >= 32) { - WRITE_RD((RS1 & 0x80000000) ? 0x80000000 : 0x7fffffff); +sreg_t val; +if (RS1 == 0) { + val = 0; +} else if (sshamt >= 32) { + val = (RS1 & 0x80000000) ? 0x80000000 : 0x7fffffff; P.set_vxsat(); +} else if (sshamt <= -32) { + val = (RS1 & 0x80000000) ? 0xffffffff : 0; +} else { + val = sshamt >= 0 ? P_SAT(32, static_cast (RS1) << sshamt) : (RS1 >> -sshamt); } -else if (sshamt <= -32) - WRITE_RD((RS1 & 0x80000000) ? 0xffffffff : 0); -else - WRITE_RD(sshamt >= 0 ? P_SAT(32, static_cast (RS1) << sshamt) : (RS1 >> -sshamt)); \ No newline at end of file + +WRITE_RD(sext32(val)); From 59b63cf58d78ccb7462d2f095b4e6d61b73ff96a Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Wed, 20 May 2026 05:46:26 -0700 Subject: [PATCH 05/12] rvp: helper macro doesn't fit some nclip operation also refine writing path to RD Signed-off-by: Chih-Min Chao --- riscv/insns/nclip.h | 2 +- riscv/insns/nclipi.h | 2 +- riscv/insns/nclipiu.h | 7 +++++-- riscv/insns/nclipr.h | 2 +- riscv/insns/nclipri.h | 6 +++--- riscv/insns/nclipriu.h | 14 +++++++------- riscv/insns/nclipru.h | 16 ++++++++-------- riscv/insns/nclipu.h | 8 ++++++-- 8 files changed, 32 insertions(+), 25 deletions(-) diff --git a/riscv/insns/nclip.h b/riscv/insns/nclip.h index f1ecfc76..fb553d43 100644 --- a/riscv/insns/nclip.h +++ b/riscv/insns/nclip.h @@ -2,4 +2,4 @@ require_extension('P'); require_rv32; sreg_t tmp = (sreg_t)P_RS1_PAIR >> (RS2 & 0x3f); int32_t result = P_SAT(32, tmp); -WRITE_RD(result); \ No newline at end of file +WRITE_RD(sext32(result)); diff --git a/riscv/insns/nclipi.h b/riscv/insns/nclipi.h index 79bc1f2a..191e2163 100644 --- a/riscv/insns/nclipi.h +++ b/riscv/insns/nclipi.h @@ -2,4 +2,4 @@ require_extension('P'); require_rv32; sreg_t tmp = (sreg_t)P_RS1_PAIR >> insn.shamtd(); int32_t result = P_SAT(32, tmp); -WRITE_RD(result); \ No newline at end of file +WRITE_RD(sext32(result)); diff --git a/riscv/insns/nclipiu.h b/riscv/insns/nclipiu.h index d8608d10..c83f5549 100644 --- a/riscv/insns/nclipiu.h +++ b/riscv/insns/nclipiu.h @@ -1,5 +1,8 @@ require_extension('P'); require_rv32; reg_t tmp = (reg_t)P_RS1_PAIR >> insn.shamtd(); -uint32_t result = P_USAT_FULL(32, (sreg_t)tmp); -WRITE_RD(result); \ No newline at end of file +if (tmp > UINT32_MAX) { + tmp = UINT32_MAX; + P.set_vxsat(); +} +WRITE_RD(sext32(tmp)); diff --git a/riscv/insns/nclipr.h b/riscv/insns/nclipr.h index e9aca14e..7e88b66b 100644 --- a/riscv/insns/nclipr.h +++ b/riscv/insns/nclipr.h @@ -8,4 +8,4 @@ if (shamt == 0) { } else { result = P_SAT(32, (val >> shamt) + ((val >> (shamt - 1)) & 1)); } -WRITE_RD(result); \ No newline at end of file +WRITE_RD(sext32(result)); diff --git a/riscv/insns/nclipri.h b/riscv/insns/nclipri.h index 17528201..6ce8715b 100644 --- a/riscv/insns/nclipri.h +++ b/riscv/insns/nclipri.h @@ -4,8 +4,8 @@ sreg_t val = (sreg_t)P_RS1_PAIR; uint32_t shamt = insn.shamtd(); sreg_t result; if (shamt == 0) { - result = P_SAT(32, val); + result = P_SAT(32, val); } else { - result = P_SAT(32, (val >> shamt) + ((val >> (shamt - 1)) & 1)); + result = P_SAT(32, (val >> shamt) + ((val >> (shamt - 1)) & 1)); } -WRITE_RD(result); \ No newline at end of file +WRITE_RD(sext32(result)); diff --git a/riscv/insns/nclipriu.h b/riscv/insns/nclipriu.h index 2595dbc8..eb34bde8 100644 --- a/riscv/insns/nclipriu.h +++ b/riscv/insns/nclipriu.h @@ -1,11 +1,11 @@ require_extension('P'); require_rv32; -reg_t val = (reg_t)P_RS1_PAIR; uint32_t shamt = insn.shamtd(); -reg_t result; -if (shamt == 0) { - result = P_USAT_FULL(32, (sreg_t)val); -} else { - result = P_USAT_FULL(32, (sreg_t)((val >> shamt) + ((val >> (shamt - 1)) & 1))); +reg_t tmp = ((((uint128_t)P_RS1_PAIR << 1) >> shamt) + 1) >> 1; + +if (tmp > UINT32_MAX) { + tmp = UINT32_MAX; + P.set_vxsat(); } -WRITE_RD(result); \ No newline at end of file +WRITE_RD(sext32(tmp)); + diff --git a/riscv/insns/nclipru.h b/riscv/insns/nclipru.h index c8044ed0..6dd660db 100644 --- a/riscv/insns/nclipru.h +++ b/riscv/insns/nclipru.h @@ -1,11 +1,11 @@ require_extension('P'); require_rv32; -reg_t val = (reg_t)P_RS1_PAIR; uint32_t shamt = RS2 & 0x3f; -reg_t result; -if (shamt == 0) { - result = P_USAT_FULL(32, (sreg_t)val); -} else { - result = P_USAT_FULL(32, (sreg_t)((val >> shamt) + ((val >> (shamt - 1)) & 1))); -} -WRITE_RD(result); \ No newline at end of file +reg_t tmp = ((((uint128_t)P_RS1_PAIR << 1) >> shamt) + 1) >> 1; + +if (tmp > UINT32_MAX) { + tmp = UINT32_MAX; + P.set_vxsat(); +} +WRITE_RD(sext32(tmp)); + diff --git a/riscv/insns/nclipu.h b/riscv/insns/nclipu.h index a1e6099d..4838b835 100644 --- a/riscv/insns/nclipu.h +++ b/riscv/insns/nclipu.h @@ -1,5 +1,9 @@ require_extension('P'); require_rv32; reg_t tmp = (reg_t)P_RS1_PAIR >> (RS2 & 0x3f); -uint32_t result = P_USAT_FULL(32, (sreg_t)tmp); -WRITE_RD(result); \ No newline at end of file +if (tmp > UINT32_MAX) { + tmp = UINT32_MAX; + P.set_vxsat(); +} + +WRITE_RD(sext32(tmp)); From 38886e3dc78fc0b08a15640d042b701e363b1964 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Thu, 21 May 2026 08:46:51 -0700 Subject: [PATCH 06/12] rvp: refine the sign-extension and extration of mulplication result Signed-off-by: Chih-Min Chao --- riscv/insns/mqrwacc.h | 3 ++- riscv/insns/mqwacc.h | 3 ++- riscv/insns/pmqrwacc_h.h | 5 +++-- riscv/insns/pmqwacc_h.h | 5 +++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/riscv/insns/mqrwacc.h b/riscv/insns/mqrwacc.h index 0aa2e73d..96d35661 100644 --- a/riscv/insns/mqrwacc.h +++ b/riscv/insns/mqrwacc.h @@ -1,3 +1,4 @@ require_extension('P'); require_rv32; -WRITE_P_RD_PAIR(P_RD_PAIR + (((sreg_t)RS1*(sreg_t)RS2 + 0x40000000) >> 31)); \ No newline at end of file +int64_t tmp = (((int128_t)(int32_t)RS1 * (int32_t)RS2) + (1 << 30)) >> 31; +WRITE_P_RD_PAIR(P_RD_PAIR + tmp); diff --git a/riscv/insns/mqwacc.h b/riscv/insns/mqwacc.h index 6f7cacdc..67510fdb 100644 --- a/riscv/insns/mqwacc.h +++ b/riscv/insns/mqwacc.h @@ -1,3 +1,4 @@ require_extension('P'); require_rv32; -WRITE_P_RD_PAIR(P_RD_PAIR + (((sreg_t)RS1*(sreg_t)RS2) >> 31)); \ No newline at end of file +int64_t tmp = (((int128_t)(int32_t)RS1 * (int32_t)RS2)) >> 31; +WRITE_P_RD_PAIR((P_RD_PAIR + tmp)); diff --git a/riscv/insns/pmqrwacc_h.h b/riscv/insns/pmqrwacc_h.h index 41ab71ea..3a741ba5 100644 --- a/riscv/insns/pmqrwacc_h.h +++ b/riscv/insns/pmqrwacc_h.h @@ -1,4 +1,5 @@ require_rv32; P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { - p_rd += (p_rs1 * p_rs2 + 0x4000) >> 15; -}) \ No newline at end of file + int64_t val = ((int64_t)(int16_t)p_rs1 * (int64_t)(int16_t)p_rs2 + 0x4000) >> 15; + p_rd += val; +}) diff --git a/riscv/insns/pmqwacc_h.h b/riscv/insns/pmqwacc_h.h index e6629270..4dbcc546 100644 --- a/riscv/insns/pmqwacc_h.h +++ b/riscv/insns/pmqwacc_h.h @@ -1,4 +1,5 @@ require_rv32; P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { - p_rd += (p_rs1 * p_rs2) >> 15; -}) \ No newline at end of file + int64_t val = ((int64_t)(int16_t)p_rs1 * (int64_t)(int16_t)p_rs2) >> 15; + p_rd += val; +}) From 6e0889925ba98aeb7b2fa580c9d756b5abed25af Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Thu, 21 May 2026 08:59:12 -0700 Subject: [PATCH 07/12] rvp: fix and simplify behavior Signed-off-by: Chih-Min Chao --- riscv/insns/pm2wsub_hx.h | 6 +-- riscv/insns/pm2wsuba_hx.h | 6 +-- riscv/insns/pssha_dhs.h | 59 ++++++++++------------------ riscv/insns/pssha_dws.h | 57 +++++++++------------------ riscv/insns/psshar_dhs.h | 81 +++++++++++---------------------------- riscv/insns/psshar_dws.h | 81 +++++++++++---------------------------- 6 files changed, 89 insertions(+), 201 deletions(-) diff --git a/riscv/insns/pm2wsub_hx.h b/riscv/insns/pm2wsub_hx.h index 81da3652..df35dc04 100644 --- a/riscv/insns/pm2wsub_hx.h +++ b/riscv/insns/pm2wsub_hx.h @@ -1,7 +1,7 @@ require_rv32; P_WIDEN_REDUCTION_CROSS_LOOP(32, 16, false, false, { if (j & 1) - p_res += p_rs1 * p_rs2; + p_res -= (int64_t)p_rs1 * p_rs2; else - p_res -= p_rs1 * p_rs2; -}) \ No newline at end of file + p_res += (int64_t)p_rs1 * p_rs2; +}) diff --git a/riscv/insns/pm2wsuba_hx.h b/riscv/insns/pm2wsuba_hx.h index 58a99d03..353a078d 100644 --- a/riscv/insns/pm2wsuba_hx.h +++ b/riscv/insns/pm2wsuba_hx.h @@ -1,7 +1,7 @@ require_rv32; P_WIDEN_REDUCTION_CROSS_LOOP(32, 16, true, false, { if (j & 1) - p_res += p_rs1 * p_rs2; - else p_res -= p_rs1 * p_rs2; -}) \ No newline at end of file + else + p_res += p_rs1 * p_rs2; +}) diff --git a/riscv/insns/pssha_dhs.h b/riscv/insns/pssha_dhs.h index e72b4cf9..c3266108 100644 --- a/riscv/insns/pssha_dhs.h +++ b/riscv/insns/pssha_dhs.h @@ -1,45 +1,26 @@ require_rv32; P_RD_RS1_DW_LOOP(16, 16, { - uint64_t bits_SMIN = (uint64_t{1} << (16 - 1)); - uint64_t bits_SMAX = ((uint64_t{1} << (16 - 1)) - 1); bool ov = false; - int8_t m = P_FIELD(RS2, 0, 8); - int8_t rev = static_cast(m); - rev = (m < 0) ? static_cast(~m + 1u) : m; - uint64_t mask = ((uint64_t{1} << 16) - 1); - p_rs1 &= mask; - if(m < 0){ - unsigned sh = ((unsigned)(uint8_t)rev > 255u) ? 255u : (unsigned)(uint8_t)rev; - uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; - - if(sh >= 16) p_rd = (uint16_t)(sign ? mask : 0u); - else{ - uint64_t shifted = (p_rs1 >> sh); - uint64_t fill = (~uint64_t{0}) << (16 - sh); - shifted |= fill; - p_rd = (uint16_t)(shifted & mask); - } - } - else{ - if(rev==0) p_rd = (uint16_t)p_rs1; - else if(rev >= 16){ - if(p_rs1==0) p_rd = 0; - else{ - ov = true; - uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; - p_rd = (uint16_t)(sign ? bits_SMIN : bits_SMAX); - } - } - else{ - uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; - uint64_t top = (p_rs1 >> (16 - rev)); - uint64_t need = sign ? ((uint64_t{1} << rev) - 1) : 0u; - ov = (top != need); - if(ov) - p_rd = (uint16_t)(sign ? bits_SMIN : bits_SMAX); - else - p_rd = (uint16_t)((p_rs1 << rev) & mask); + int8_t sshamt = P_FIELD(RS2, 0, 8); + int32_t val = p_rs1; + if (sshamt < 0) { + val = (int16_t)(val >> std::min(-sshamt, 16)); + } else if (sshamt >= 16 && val != 0){ + val = val > 0 ? INT16_MAX : INT16_MIN; + ov = true; + } else if (val != 0) { + int32_t tmp = (int32_t)val << sshamt; + if (tmp > INT16_MAX) { + val = INT16_MAX; + ov = true; + } else if (tmp < INT16_MIN) { + val = INT16_MIN; + ov = true; + } else { + val = tmp; } } + p_rd = val; + if (ov) P.set_vxsat(); -}) \ No newline at end of file +}) diff --git a/riscv/insns/pssha_dws.h b/riscv/insns/pssha_dws.h index 8048daff..98bb4e89 100644 --- a/riscv/insns/pssha_dws.h +++ b/riscv/insns/pssha_dws.h @@ -1,45 +1,26 @@ require_rv32; P_RD_RS1_DW_LOOP(32, 32, { - uint64_t bits_SMIN = (uint64_t{1} << (32 - 1)); - uint64_t bits_SMAX = ((uint64_t{1} << (32 - 1)) - 1); bool ov = false; - int8_t m = P_FIELD(RS2, 0, 8); - int8_t rev = static_cast(m); - rev = (m < 0) ? static_cast(~m + 1u) : m; - uint64_t mask = ((uint64_t{1} << 32) - 1); - p_rs1 &= mask; - if(m < 0){ - unsigned sh = ((unsigned)(uint8_t)rev > 255u) ? 255u : (unsigned)(uint8_t)rev; - uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; - - if(sh >= 32) p_rd = (uint32_t)(sign ? mask : 0u); - else{ - uint64_t shifted = (p_rs1 >> sh); - uint64_t fill = (~uint64_t{0}) << (32 - sh); - shifted |= fill; - p_rd = (uint32_t)(shifted & mask); - } - } - else{ - if(rev==0) p_rd = (uint32_t)p_rs1; - else if(rev >= 32){ - if(p_rs1==0) p_rd = 0; - else{ - ov = true; - uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; - p_rd = (uint32_t)(sign ? bits_SMIN : bits_SMAX); - } - } - else{ - uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; - uint64_t top = (p_rs1 >> (32 - rev)); - uint64_t need = sign ? ((uint64_t{1} << rev) - 1) : 0u; - ov = (top != need); - if(ov) - p_rd = (uint32_t)(sign ? bits_SMIN : bits_SMAX); - else - p_rd = (uint32_t)((p_rs1 << rev) & mask); + int8_t sshamt = P_FIELD(RS2, 0, 8); + int64_t val = p_rs1; + if (sshamt < 0) { + val = (int32_t)(val >> std::min(-sshamt, 32)); + } else if (sshamt >= 32 && val != 0){ + val = val > 0 ? INT32_MAX : INT32_MIN; + ov = true; + } else if (val != 0) { + int64_t tmp = (int64_t)val << sshamt; + if (tmp > INT32_MAX) { + val = INT32_MAX; + ov = true; + } else if (tmp < INT32_MIN) { + val = INT32_MIN; + ov = true; + } else { + val = tmp; } } + p_rd = val; + if (ov) P.set_vxsat(); }) diff --git a/riscv/insns/psshar_dhs.h b/riscv/insns/psshar_dhs.h index e1ccc6b9..ed5a0fb1 100644 --- a/riscv/insns/psshar_dhs.h +++ b/riscv/insns/psshar_dhs.h @@ -1,64 +1,27 @@ require_rv32; P_RD_RS1_DW_LOOP(16, 16, { - uint64_t bits_SMIN = (uint64_t{1} << (16 - 1)); - uint64_t bits_SMAX = ((uint64_t{1} << (16 - 1)) - 1); - bool ov = false; - int8_t m = P_FIELD(RS2, 0, 8); - int8_t rev = static_cast(m); - rev = (m < 0) ? static_cast(~m + 1u) : m; - uint64_t mask = ((uint64_t{1} << 16) - 1); - p_rs1 &= mask; - if(m < 0){ - if ((rev & 0xFFu) == 0u) - p_rd = (uint16_t)p_rs1; - else{ - int128_t v_sext; - bool neg = ((p_rs1 >> (16 - 1)) & 1u); - if(!neg) v_sext = static_cast(p_rs1); - else v_sext = static_cast((~static_cast(0) << 16) | static_cast(p_rs1)); - int128_t v_cat0 = v_sext << 1; - - unsigned sh = ((unsigned)(uint8_t)rev > 255u) ? 255u : (unsigned)(uint8_t)rev; - - int128_t sra_val; - if(sh == 0) - sra_val = v_cat0; - else if(sh >=127) - sra_val = (v_cat0 < 0) ? static_cast(-1) : static_cast(0); - else{ - int128_t ux = static_cast(v_cat0); - int128_t shifted = ux >> sh; - if(v_cat0 < 0) - shifted |= (~static_cast(0)) << (128 - sh); - sra_val = static_cast(shifted); - } - - int128_t plus1 = sra_val + static_cast(1); - uint128_t ures = static_cast(plus1); - p_rd = (uint16_t)(static_cast((ures >> 1) & static_cast(mask))); - } - } - else{ - if(rev==0) p_rd = (uint16_t)p_rs1; - else if(rev >= 16){ - if(p_rs1==0) - p_rd = 0; - else{ - ov = true; - uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; - p_rd = (uint16_t)(sign ? bits_SMIN : bits_SMAX); - } - } - else{ - uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; - uint64_t top = (p_rs1 >> (16 - rev)); - uint64_t need = sign ? ((uint64_t{1} << rev) - 1) : 0u; - ov = (top != need); - if(ov) - p_rd = (uint16_t)(sign ? bits_SMIN : bits_SMAX); - else - p_rd = (uint16_t)((p_rs1 << rev) & mask); - } + bool ov = false; + int8_t sshamt = P_FIELD(RS2, 0, 8); + int32_t val = p_rs1; + if (sshamt < 0) { + val = (val << 1) >> std::min(-sshamt, 16); + val = (int16_t)((val + 1) >> 1); + } else if (sshamt >= 16 && val != 0){ + val = val > 0 ? INT16_MAX : INT16_MIN; + ov = true; + } else if (val != 0) { + int32_t tmp = (int32_t)val << sshamt; + if (tmp > INT16_MAX) { + val = INT16_MAX; + ov = true; + } else if (tmp < INT16_MIN) { + val = INT16_MIN; + ov = true; + } else { + val = tmp; } + } + p_rd = val; + if (ov) P.set_vxsat(); }) diff --git a/riscv/insns/psshar_dws.h b/riscv/insns/psshar_dws.h index 95718649..b73f0cf9 100644 --- a/riscv/insns/psshar_dws.h +++ b/riscv/insns/psshar_dws.h @@ -1,64 +1,27 @@ require_rv32; P_RD_RS1_DW_LOOP(32, 32, { - uint64_t bits_SMIN = (uint64_t{1} << (32 - 1)); - uint64_t bits_SMAX = ((uint64_t{1} << (32 - 1)) - 1); - bool ov = false; - int8_t m = P_FIELD(RS2, 0, 8); - int8_t rev = static_cast(m); - rev = (m < 0) ? static_cast(~m + 1u) : m; - uint64_t mask = ((uint64_t{1} << 32) - 1); - p_rs1 &= mask; - if(m < 0){ - if ((rev & 0xFFu) == 0u) - p_rd = (uint32_t)p_rs1; - else{ - int128_t v_sext; - bool neg = ((p_rs1 >> (32 - 1)) & 1u); - if(!neg) v_sext = static_cast(p_rs1); - else v_sext = static_cast((~static_cast(0) << 32) | static_cast(p_rs1)); - int128_t v_cat0 = v_sext << 1; - - unsigned sh = ((unsigned)(uint8_t)rev > 255u) ? 255u : (unsigned)(uint8_t)rev; - - int128_t sra_val; - if(sh == 0) - sra_val = v_cat0; - else if(sh >=127) - sra_val = (v_cat0 < 0) ? static_cast(-1) : static_cast(0); - else{ - int128_t ux = static_cast(v_cat0); - int128_t shifted = ux >> sh; - if(v_cat0 < 0) - shifted |= (~static_cast(0)) << (128 - sh); - sra_val = static_cast(shifted); - } - - int128_t plus1 = sra_val + static_cast(1); - uint128_t ures = static_cast(plus1); - p_rd = (uint32_t)(static_cast((ures >> 1) & static_cast(mask))); - } - } - else{ - if(rev==0) p_rd = (uint32_t)p_rs1; - else if(rev >= 32){ - if(p_rs1==0) - p_rd = 0; - else{ - ov = true; - uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; - p_rd = (uint32_t)(sign ? bits_SMIN : bits_SMAX); - } - } - else{ - uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; - uint64_t top = (p_rs1 >> (32 - rev)); - uint64_t need = sign ? ((uint64_t{1} << rev) - 1) : 0u; - ov = (top != need); - if(ov) - p_rd = (uint32_t)(sign ? bits_SMIN : bits_SMAX); - else - p_rd = (uint32_t)((p_rs1 << rev) & mask); - } + bool ov = false; + int8_t sshamt = P_FIELD(RS2, 0, 8); + int64_t val = p_rs1; + if (sshamt < 0) { + val = (val << 1) >> std::min(-sshamt, 32); + val = (int32_t)((val + 1) >> 1); + } else if (sshamt >= 32 && val != 0){ + val = val > 0 ? INT32_MAX : INT32_MIN; + ov = true; + } else if (val != 0) { + int64_t tmp = (int64_t)val << sshamt; + if (tmp > INT32_MAX) { + val = INT32_MAX; + ov = true; + } else if (tmp < INT32_MIN) { + val = INT32_MIN; + ov = true; + } else { + val = tmp; } + } + p_rd = val; + if (ov) P.set_vxsat(); }) From 36c40b4853cd711ce7b897db531b579b22affa27 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Wed, 27 May 2026 07:59:33 -0700 Subject: [PATCH 08/12] rvp: add missing vxsat updating Signed-off-by: Chih-Min Chao --- riscv/insns/psadd_b.h | 4 +++- riscv/insns/psadd_db.h | 4 +++- riscv/insns/psadd_dh.h | 4 +++- riscv/insns/psadd_dw.h | 4 +++- riscv/insns/psadd_h.h | 4 +++- riscv/insns/psadd_w.h | 2 ++ riscv/insns/psaddu_b.h | 4 +++- riscv/insns/psaddu_db.h | 4 +++- riscv/insns/psaddu_dh.h | 4 +++- riscv/insns/psaddu_dw.h | 4 +++- riscv/insns/psaddu_h.h | 4 +++- riscv/insns/psaddu_w.h | 2 ++ riscv/insns/pssub_b.h | 4 +++- riscv/insns/pssub_db.h | 4 +++- riscv/insns/pssub_dh.h | 4 +++- riscv/insns/pssub_dw.h | 4 +++- riscv/insns/pssub_h.h | 4 +++- riscv/insns/pssub_w.h | 2 ++ riscv/insns/pssubu_b.h | 4 +++- riscv/insns/pssubu_db.h | 4 +++- riscv/insns/pssubu_dh.h | 4 +++- riscv/insns/pssubu_dw.h | 4 +++- riscv/insns/pssubu_h.h | 4 +++- riscv/insns/pssubu_w.h | 2 ++ riscv/insns/saddu.h | 1 + riscv/insns/ssub.h | 4 +++- riscv/insns/ssubu.h | 5 ++++- 27 files changed, 76 insertions(+), 22 deletions(-) diff --git a/riscv/insns/psadd_b.h b/riscv/insns/psadd_b.h index a024d4d0..43998751 100644 --- a/riscv/insns/psadd_b.h +++ b/riscv/insns/psadd_b.h @@ -1,4 +1,6 @@ P_RD_RS1_RS2_LOOP(8,8,8, { bool sat = false; p_rd = (sat_add(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psadd_db.h b/riscv/insns/psadd_db.h index 3c297868..f2a6c52e 100644 --- a/riscv/insns/psadd_db.h +++ b/riscv/insns/psadd_db.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_LOOP(8,8,8, { bool sat = false; p_rd = (sat_add(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psadd_dh.h b/riscv/insns/psadd_dh.h index bd14a581..7549d86c 100644 --- a/riscv/insns/psadd_dh.h +++ b/riscv/insns/psadd_dh.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_LOOP(16,16,16, { bool sat = false; p_rd = (sat_add(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psadd_dw.h b/riscv/insns/psadd_dw.h index 5ec3466d..dfe0f130 100644 --- a/riscv/insns/psadd_dw.h +++ b/riscv/insns/psadd_dw.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_LOOP(32,32,32, { bool sat = false; p_rd = (sat_add(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psadd_h.h b/riscv/insns/psadd_h.h index 47af97ad..ba5af96e 100644 --- a/riscv/insns/psadd_h.h +++ b/riscv/insns/psadd_h.h @@ -1,4 +1,6 @@ P_RD_RS1_RS2_LOOP(16,16,16, { bool sat = false; p_rd = (sat_add(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psadd_w.h b/riscv/insns/psadd_w.h index 7702b936..e170e9c8 100644 --- a/riscv/insns/psadd_w.h +++ b/riscv/insns/psadd_w.h @@ -2,5 +2,7 @@ require_rv64; P_RD_RS1_RS2_LOOP(32,32,32, { bool sat = false; p_rd = (sat_add(p_rs1, p_rs2, sat)); + if (sat) + P.set_vxsat(); } ) diff --git a/riscv/insns/psaddu_b.h b/riscv/insns/psaddu_b.h index 491fc2d3..535c99a0 100644 --- a/riscv/insns/psaddu_b.h +++ b/riscv/insns/psaddu_b.h @@ -1,4 +1,6 @@ P_RD_RS1_RS2_ULOOP(8,8,8, { bool sat = false; p_rd = (sat_addu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psaddu_db.h b/riscv/insns/psaddu_db.h index a181f24a..c9acd5bd 100644 --- a/riscv/insns/psaddu_db.h +++ b/riscv/insns/psaddu_db.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_ULOOP(8,8,8, { bool sat = false; p_rd = (sat_addu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psaddu_dh.h b/riscv/insns/psaddu_dh.h index 035d91fc..31aa12f5 100644 --- a/riscv/insns/psaddu_dh.h +++ b/riscv/insns/psaddu_dh.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_ULOOP(16,16,16, { bool sat = false; p_rd = (sat_addu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psaddu_dw.h b/riscv/insns/psaddu_dw.h index ebc4d8bb..cfc92178 100644 --- a/riscv/insns/psaddu_dw.h +++ b/riscv/insns/psaddu_dw.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_ULOOP(32,32,32, { bool sat = false; p_rd = (sat_addu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psaddu_h.h b/riscv/insns/psaddu_h.h index f28d0f32..67f2df23 100644 --- a/riscv/insns/psaddu_h.h +++ b/riscv/insns/psaddu_h.h @@ -1,4 +1,6 @@ P_RD_RS1_RS2_ULOOP(16,16,16, { bool sat = false; p_rd = (sat_addu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/psaddu_w.h b/riscv/insns/psaddu_w.h index 4ff52136..eb7453ac 100644 --- a/riscv/insns/psaddu_w.h +++ b/riscv/insns/psaddu_w.h @@ -2,5 +2,7 @@ require_rv64; P_RD_RS1_RS2_ULOOP(32,32,32, { bool sat = false; p_rd = (sat_addu(p_rs1, p_rs2, sat)); + if (sat) + P.set_vxsat(); } ) diff --git a/riscv/insns/pssub_b.h b/riscv/insns/pssub_b.h index 91a89aa1..d90fb6e7 100644 --- a/riscv/insns/pssub_b.h +++ b/riscv/insns/pssub_b.h @@ -1,4 +1,6 @@ P_RD_RS1_RS2_LOOP(8,8,8, { bool sat = false; p_rd = (sat_sub(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssub_db.h b/riscv/insns/pssub_db.h index 1fd3d79e..82c47870 100644 --- a/riscv/insns/pssub_db.h +++ b/riscv/insns/pssub_db.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_LOOP(8,8,8, { bool sat = false; p_rd = (sat_sub(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssub_dh.h b/riscv/insns/pssub_dh.h index 8c16a47c..5014e450 100644 --- a/riscv/insns/pssub_dh.h +++ b/riscv/insns/pssub_dh.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_LOOP(16,16,16, { bool sat = false; p_rd = (sat_sub(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssub_dw.h b/riscv/insns/pssub_dw.h index be55dc5a..af3583b0 100644 --- a/riscv/insns/pssub_dw.h +++ b/riscv/insns/pssub_dw.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_LOOP(32,32,32, { bool sat = false; p_rd = (sat_sub(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssub_h.h b/riscv/insns/pssub_h.h index db88d680..d05622a0 100644 --- a/riscv/insns/pssub_h.h +++ b/riscv/insns/pssub_h.h @@ -1,4 +1,6 @@ P_RD_RS1_RS2_LOOP(16,16,16, { bool sat = false; p_rd = (sat_sub(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssub_w.h b/riscv/insns/pssub_w.h index 0cfa1072..87336aeb 100644 --- a/riscv/insns/pssub_w.h +++ b/riscv/insns/pssub_w.h @@ -2,5 +2,7 @@ require_rv64; P_RD_RS1_RS2_LOOP(32,32,32, { bool sat = false; p_rd = (sat_sub(p_rs1, p_rs2, sat)); + if (sat) + P.set_vxsat(); } ) diff --git a/riscv/insns/pssubu_b.h b/riscv/insns/pssubu_b.h index 3fd44bee..5d1f54ef 100644 --- a/riscv/insns/pssubu_b.h +++ b/riscv/insns/pssubu_b.h @@ -1,4 +1,6 @@ P_RD_RS1_RS2_ULOOP(8,8,8, { bool sat = false; p_rd = (sat_subu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssubu_db.h b/riscv/insns/pssubu_db.h index fd564a5f..20034963 100644 --- a/riscv/insns/pssubu_db.h +++ b/riscv/insns/pssubu_db.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_ULOOP(8,8,8, { bool sat = false; p_rd = (sat_subu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssubu_dh.h b/riscv/insns/pssubu_dh.h index b910ce5d..c20949c9 100644 --- a/riscv/insns/pssubu_dh.h +++ b/riscv/insns/pssubu_dh.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_ULOOP(16,16,16, { bool sat = false; p_rd = (sat_subu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssubu_dw.h b/riscv/insns/pssubu_dw.h index aa9063a2..4c6ecaf9 100644 --- a/riscv/insns/pssubu_dw.h +++ b/riscv/insns/pssubu_dw.h @@ -2,4 +2,6 @@ require_rv32; P_RD_RS1_RS2_DW_ULOOP(32,32,32, { bool sat = false; p_rd = (sat_subu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssubu_h.h b/riscv/insns/pssubu_h.h index de3ff72a..b90222a2 100644 --- a/riscv/insns/pssubu_h.h +++ b/riscv/insns/pssubu_h.h @@ -1,4 +1,6 @@ P_RD_RS1_RS2_ULOOP(16,16,16, { bool sat = false; p_rd = (sat_subu(p_rs1, p_rs2, sat)); -}) \ No newline at end of file + if (sat) + P.set_vxsat(); +}) diff --git a/riscv/insns/pssubu_w.h b/riscv/insns/pssubu_w.h index e4a42adc..8f1ad943 100644 --- a/riscv/insns/pssubu_w.h +++ b/riscv/insns/pssubu_w.h @@ -2,5 +2,7 @@ require_rv64; P_RD_RS1_RS2_ULOOP(32,32,32, { bool sat = false; p_rd = (sat_subu(p_rs1, p_rs2, sat)); + if (sat) + P.set_vxsat(); } ) diff --git a/riscv/insns/saddu.h b/riscv/insns/saddu.h index 3128bc28..e01d77c3 100644 --- a/riscv/insns/saddu.h +++ b/riscv/insns/saddu.h @@ -4,4 +4,5 @@ bool sat = false; reg_t tmp = sat_addu(RS1, RS2, sat); if (sat) P.set_vxsat(); + WRITE_RD(sext32(tmp)); diff --git a/riscv/insns/ssub.h b/riscv/insns/ssub.h index f3db9b4b..40f147f3 100644 --- a/riscv/insns/ssub.h +++ b/riscv/insns/ssub.h @@ -2,4 +2,6 @@ require_extension('P'); require_rv32; bool sat = false; int32_t p_rd = sat_sub(RS1, RS2, sat); -WRITE_RD(p_rd); \ No newline at end of file +if (sat) + P.set_vxsat(); +WRITE_RD(sext32(p_rd)); diff --git a/riscv/insns/ssubu.h b/riscv/insns/ssubu.h index c4aac5d3..fde181ef 100644 --- a/riscv/insns/ssubu.h +++ b/riscv/insns/ssubu.h @@ -1,4 +1,7 @@ require_extension('P'); require_rv32; bool sat = false; -WRITE_RD(sat_subu(RS1, RS2, sat)); \ No newline at end of file +uint32_t p_rd = sat_subu(RS1, RS2, sat); +if (sat) + P.set_vxsat(); +WRITE_RD(sext32(p_rd)); From 4796690c71e262dab9dedf138aeae7d95c52a8bd Mon Sep 17 00:00:00 2001 From: Max Chou Date: Fri, 29 May 2026 11:15:19 -0700 Subject: [PATCH 09/12] rvp: Fix multiply-accumulate result extraction shift amount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Corrects shift amount for extracting bits [47:16] from 48-bit multiply-accumulate products. Implementation used 32-bit shift but spec requires 16-bit shift to extract high portion. Fixed instructions: - MHACC.H0: P-ext spec - MHACC.H1: P-ext spec - MHACCSU.H0: P-ext spec - MHACCSU.H1: P-ext spec Changed: mres >> 32 → mres >> 16 Signed-off-by: Max Chou --- riscv/insns/mhacc_h0.h | 2 +- riscv/insns/mhacc_h1.h | 2 +- riscv/insns/mhaccsu_h0.h | 2 +- riscv/insns/mhaccsu_h1.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/riscv/insns/mhacc_h0.h b/riscv/insns/mhacc_h0.h index 699e9165..bb254534 100644 --- a/riscv/insns/mhacc_h0.h +++ b/riscv/insns/mhacc_h0.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * sext32(P_FIELD(RS2, 0, 16)); -WRITE_RD(RD + (mres >> 32)); \ No newline at end of file +WRITE_RD(RD + (mres >> 16)); \ No newline at end of file diff --git a/riscv/insns/mhacc_h1.h b/riscv/insns/mhacc_h1.h index ea228fe6..7565c358 100644 --- a/riscv/insns/mhacc_h1.h +++ b/riscv/insns/mhacc_h1.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * sext32(P_FIELD(RS2, 1, 16)); -WRITE_RD(RD + (mres >> 32)); \ No newline at end of file +WRITE_RD(RD + (mres >> 16)); \ No newline at end of file diff --git a/riscv/insns/mhaccsu_h0.h b/riscv/insns/mhaccsu_h0.h index e89f309b..d455141d 100644 --- a/riscv/insns/mhaccsu_h0.h +++ b/riscv/insns/mhaccsu_h0.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * (uint32_t)P_FIELD(RS2, 0, 16); -WRITE_RD(RD + (mres >> 32)); \ No newline at end of file +WRITE_RD(RD + (mres >> 16)); \ No newline at end of file diff --git a/riscv/insns/mhaccsu_h1.h b/riscv/insns/mhaccsu_h1.h index e49a15f6..d990e49b 100644 --- a/riscv/insns/mhaccsu_h1.h +++ b/riscv/insns/mhaccsu_h1.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * (uint32_t)P_FIELD(RS2, 1, 16); -WRITE_RD(RD + (mres >> 32)); \ No newline at end of file +WRITE_RD(RD + (mres >> 16)); \ No newline at end of file From 85c84f0d2769807aaa38e368772e1763a25a32fb Mon Sep 17 00:00:00 2001 From: Max Chou Date: Fri, 29 May 2026 11:15:34 -0700 Subject: [PATCH 10/12] rvp: Fix packed multiply-subtract operation logic Corrects swapped add/subtract operators in packed 2-way multiply loop. Spec requires (p0 - p1) but implementation computed (p1 - p0). Even elements should add, odd elements should subtract. Fixed instructions: - PM2WSUB.H: P-ext spec - PM2WSUBA.H: P-ext spec Changed: Swapped += and -= for (j & 1) conditional Signed-off-by: Max Chou --- riscv/insns/pm2wsub_h.h | 4 ++-- riscv/insns/pm2wsuba_h.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/riscv/insns/pm2wsub_h.h b/riscv/insns/pm2wsub_h.h index 903cbe30..e960c404 100644 --- a/riscv/insns/pm2wsub_h.h +++ b/riscv/insns/pm2wsub_h.h @@ -1,7 +1,7 @@ require_rv32; P_WIDEN_REDUCTION_LOOP(32, 16, false, false, { if (j & 1) - p_res += p_rs1 * p_rs2; - else p_res -= p_rs1 * p_rs2; + else + p_res += p_rs1 * p_rs2; }) \ No newline at end of file diff --git a/riscv/insns/pm2wsuba_h.h b/riscv/insns/pm2wsuba_h.h index 600b77e2..dae5c0a7 100644 --- a/riscv/insns/pm2wsuba_h.h +++ b/riscv/insns/pm2wsuba_h.h @@ -1,7 +1,7 @@ require_rv32; P_WIDEN_REDUCTION_LOOP(32, 16, true, false, { if (j & 1) - p_res += p_rs1 * p_rs2; - else p_res -= p_rs1 * p_rs2; + else + p_res += p_rs1 * p_rs2; }) \ No newline at end of file From 5c1a3c40bfe678fa28d44bf3e85abcdede9c0e4d Mon Sep 17 00:00:00 2001 From: Max Chou Date: Fri, 29 May 2026 11:15:45 -0700 Subject: [PATCH 11/12] rvp: Fix shift amount masking in PSLL.DWS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use 5-bit mask (0x1F) for shift amount instead of 8-bit field extraction. Spec defines rs2[4:0] as shift amount. Also removes incorrect >= 32 check that zeroed result. Fixed instruction: - PSLL.DWS: P-ext spec Changed: P_FIELD(RS2, 0, 8) with >= 32 check → RS2 & 0x1F Signed-off-by: Max Chou --- riscv/insns/psll_dws.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/riscv/insns/psll_dws.h b/riscv/insns/psll_dws.h index ec71edbf..578814fb 100644 --- a/riscv/insns/psll_dws.h +++ b/riscv/insns/psll_dws.h @@ -1,7 +1,6 @@ require_rv32; P_RD_RS1_DW_LOOP(32, 32, { - uint8_t m = P_FIELD(RS2, 0, 8); + uint8_t m = RS2 & 0x1F; const uint64_t maskN = 0xFFFFFFFFull; - if (m >= 32) p_rd = 0; - else p_rd = (uint32_t)((p_rs1 << m) & maskN); + p_rd = (uint32_t)((p_rs1 << m) & maskN); }) \ No newline at end of file From f35109939a002dcdb959c7980328d93aca009d6f Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Wed, 24 Jun 2026 01:33:48 -0700 Subject: [PATCH 12/12] rvp: some rv32 multiplication instructions require extra sign-extension Signed-off-by: Chih-Min Chao --- riscv/insns/mhacc.h | 2 +- riscv/insns/mhacc_h0.h | 2 +- riscv/insns/mhacc_h1.h | 2 +- riscv/insns/mhaccsu.h | 2 +- riscv/insns/mhaccsu_h0.h | 2 +- riscv/insns/mhaccsu_h1.h | 2 +- riscv/insns/mhaccu.h | 2 +- riscv/insns/mhracc.h | 2 +- riscv/insns/mhraccsu.h | 2 +- riscv/insns/mhraccu.h | 2 +- riscv/insns/mulhr.h | 2 +- riscv/insns/mulhrsu.h | 2 +- riscv/insns/mulhru.h | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/riscv/insns/mhacc.h b/riscv/insns/mhacc.h index 77de911d..200bf492 100644 --- a/riscv/insns/mhacc.h +++ b/riscv/insns/mhacc.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * sext32(RS2); -WRITE_RD(RD + (mres >> 32)); \ No newline at end of file +WRITE_RD(sext32(RD + (mres >> 32))); diff --git a/riscv/insns/mhacc_h0.h b/riscv/insns/mhacc_h0.h index bb254534..058a19b9 100644 --- a/riscv/insns/mhacc_h0.h +++ b/riscv/insns/mhacc_h0.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * sext32(P_FIELD(RS2, 0, 16)); -WRITE_RD(RD + (mres >> 16)); \ No newline at end of file +WRITE_RD(sext32(RD + (mres >> 16))); diff --git a/riscv/insns/mhacc_h1.h b/riscv/insns/mhacc_h1.h index 7565c358..2a026de5 100644 --- a/riscv/insns/mhacc_h1.h +++ b/riscv/insns/mhacc_h1.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * sext32(P_FIELD(RS2, 1, 16)); -WRITE_RD(RD + (mres >> 16)); \ No newline at end of file +WRITE_RD(sext32(RD + (mres >> 16))); diff --git a/riscv/insns/mhaccsu.h b/riscv/insns/mhaccsu.h index 328355c1..53534894 100644 --- a/riscv/insns/mhaccsu.h +++ b/riscv/insns/mhaccsu.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * reg_t((uint32_t)RS2); -WRITE_RD(RD + (mres >> 32)); \ No newline at end of file +WRITE_RD(sext32(RD + (mres >> 32))); diff --git a/riscv/insns/mhaccsu_h0.h b/riscv/insns/mhaccsu_h0.h index d455141d..8cd6e12f 100644 --- a/riscv/insns/mhaccsu_h0.h +++ b/riscv/insns/mhaccsu_h0.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * (uint32_t)P_FIELD(RS2, 0, 16); -WRITE_RD(RD + (mres >> 16)); \ No newline at end of file +WRITE_RD(sext32(RD + (mres >> 16))); diff --git a/riscv/insns/mhaccsu_h1.h b/riscv/insns/mhaccsu_h1.h index d990e49b..0df57ae6 100644 --- a/riscv/insns/mhaccsu_h1.h +++ b/riscv/insns/mhaccsu_h1.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * (uint32_t)P_FIELD(RS2, 1, 16); -WRITE_RD(RD + (mres >> 16)); \ No newline at end of file +WRITE_RD(sext32(RD + (mres >> 16))); diff --git a/riscv/insns/mhaccu.h b/riscv/insns/mhaccu.h index e9fb8020..016292b0 100644 --- a/riscv/insns/mhaccu.h +++ b/riscv/insns/mhaccu.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; uint64_t mres = reg_t((uint32_t)RS1) * reg_t((uint32_t)RS2); -WRITE_RD(RD + (mres >> 32)); \ No newline at end of file +WRITE_RD(sext32(RD + (mres >> 32))); diff --git a/riscv/insns/mhracc.h b/riscv/insns/mhracc.h index 902b0e56..3fcd94bf 100644 --- a/riscv/insns/mhracc.h +++ b/riscv/insns/mhracc.h @@ -2,4 +2,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext32(RS1) * sext32(RS2); int32_t round = ((mres >> 31) + 1) >> 1; -WRITE_RD(RD + round); \ No newline at end of file +WRITE_RD(sext32(RD + round)); diff --git a/riscv/insns/mhraccsu.h b/riscv/insns/mhraccsu.h index 5d676ba6..f7f0ce16 100644 --- a/riscv/insns/mhraccsu.h +++ b/riscv/insns/mhraccsu.h @@ -2,4 +2,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext(RS1,64) * reg_t((uint32_t)RS2); int32_t round = ((mres >> 31) + 1) >> 1; -WRITE_RD(RD + round); \ No newline at end of file +WRITE_RD(sext32(RD + round)); diff --git a/riscv/insns/mhraccu.h b/riscv/insns/mhraccu.h index 9cf5e5a4..285a47b2 100644 --- a/riscv/insns/mhraccu.h +++ b/riscv/insns/mhraccu.h @@ -2,4 +2,4 @@ require_extension('P'); require_rv32; reg_t mres = reg_t((uint32_t)RS1) * reg_t((uint32_t)RS2); uint32_t round = ((mres >> 31) + 1) >> 1; -WRITE_RD(RD + round); \ No newline at end of file +WRITE_RD(sext32(RD + round)); diff --git a/riscv/insns/mulhr.h b/riscv/insns/mulhr.h index 527d2a2f..80d6b69c 100644 --- a/riscv/insns/mulhr.h +++ b/riscv/insns/mulhr.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; int64_t mres = sext(RS1,64) * sext(RS2,64); -WRITE_RD(((mres >> 31) + 1) >> 1); \ No newline at end of file +WRITE_RD(sext32(((mres >> 31) + 1) >> 1)); diff --git a/riscv/insns/mulhrsu.h b/riscv/insns/mulhrsu.h index bbd7619b..395802f9 100644 --- a/riscv/insns/mulhrsu.h +++ b/riscv/insns/mulhrsu.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = sext(RS1,64) * reg_t((uint32_t)RS2); -WRITE_RD(((mres >> 31) + 1) >> 1); \ No newline at end of file +WRITE_RD(sext32(((mres >> 31) + 1) >> 1)); diff --git a/riscv/insns/mulhru.h b/riscv/insns/mulhru.h index 51cf38cb..4460f3b2 100644 --- a/riscv/insns/mulhru.h +++ b/riscv/insns/mulhru.h @@ -1,4 +1,4 @@ require_extension('P'); require_rv32; sreg_t mres = reg_t((uint32_t)RS1) * reg_t((uint32_t)RS2); -WRITE_RD(((mres >> 31) + 1) >> 1); \ No newline at end of file +WRITE_RD(sext32(((mres >> 31) + 1) >> 1));