From 8b1ad630880b2f4d9813179822b02faa57375bc1 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Tue, 19 May 2026 23:56:18 -0700 Subject: [PATCH] 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));