From cfa8d89635c29f2548121c116ce0e348d327c347 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 22 Jul 2026 19:20:06 -0700 Subject: [PATCH 1/2] Fix PNCLIPUP.W by avoiding signed arithmetic Signed-off-by: Andrew Waterman --- riscv/insns/pnclipiu_b.h | 4 ++-- riscv/insns/pnclipiu_h.h | 4 ++-- riscv/insns/pnclipriu_b.h | 4 ++-- riscv/insns/pnclipriu_h.h | 4 ++-- riscv/insns/pnclipru_bs.h | 4 ++-- riscv/insns/pnclipru_hs.h | 4 ++-- riscv/insns/pnclipu_bs.h | 4 ++-- riscv/insns/pnclipu_hs.h | 4 ++-- riscv/insns/pnclipup_b.h | 2 +- riscv/insns/pnclipup_h.h | 2 +- riscv/insns/pnclipup_w.h | 4 ++-- riscv/p_ext_macros.h | 11 +++++------ 12 files changed, 25 insertions(+), 26 deletions(-) diff --git a/riscv/insns/pnclipiu_b.h b/riscv/insns/pnclipiu_b.h index fadf004d..c9496ea3 100644 --- a/riscv/insns/pnclipiu_b.h +++ b/riscv/insns/pnclipiu_b.h @@ -1,4 +1,4 @@ require_rv32; P_NARROW_RD_RS1_ULOOP(8, 16, { - p_rd = P_USAT_FULL(8, (sreg_t)(p_rs1 >> insn.shamth())); -}) \ No newline at end of file + p_rd = P_USAT_FULL(8, p_rs1 >> insn.shamth()); +}) diff --git a/riscv/insns/pnclipiu_h.h b/riscv/insns/pnclipiu_h.h index ac490333..601979ef 100644 --- a/riscv/insns/pnclipiu_h.h +++ b/riscv/insns/pnclipiu_h.h @@ -1,4 +1,4 @@ require_rv32; P_NARROW_RD_RS1_ULOOP(16, 32, { - p_rd = P_USAT_FULL(16, (sreg_t)(p_rs1 >> insn.shamtw())); -}) \ No newline at end of file + p_rd = P_USAT_FULL(16, p_rs1 >> insn.shamtw()); +}) diff --git a/riscv/insns/pnclipriu_b.h b/riscv/insns/pnclipriu_b.h index bb55a149..450d0a89 100644 --- a/riscv/insns/pnclipriu_b.h +++ b/riscv/insns/pnclipriu_b.h @@ -9,5 +9,5 @@ P_NARROW_RD_RS1_ULOOP(8, 16, { uint32_t roundbit = (p_rs1 >> (shamt - 1)) & 1; result = shifted + roundbit; } - p_rd = P_USAT_FULL(8, (sreg_t)result); -}) \ No newline at end of file + p_rd = P_USAT_FULL(8, result); +}) diff --git a/riscv/insns/pnclipriu_h.h b/riscv/insns/pnclipriu_h.h index 4d2dbd9b..cc6a2d1a 100644 --- a/riscv/insns/pnclipriu_h.h +++ b/riscv/insns/pnclipriu_h.h @@ -9,5 +9,5 @@ P_NARROW_RD_RS1_ULOOP(16, 32, { uint32_t roundbit = (p_rs1 >> (shamt - 1)) & 1; result = shifted + roundbit; } - p_rd = P_USAT_FULL(16, (sreg_t)result); -}) \ No newline at end of file + p_rd = P_USAT_FULL(16, result); +}) diff --git a/riscv/insns/pnclipru_bs.h b/riscv/insns/pnclipru_bs.h index 25921dc6..e4fa6e3b 100644 --- a/riscv/insns/pnclipru_bs.h +++ b/riscv/insns/pnclipru_bs.h @@ -9,5 +9,5 @@ P_NARROW_RD_RS1_ULOOP(8, 16, { uint32_t roundbit = (p_rs1 >> (shamt - 1)) & 1; result = shifted + roundbit; } - p_rd = P_USAT_FULL(8, (sreg_t)result); -}) \ No newline at end of file + p_rd = P_USAT_FULL(8, result); +}) diff --git a/riscv/insns/pnclipru_hs.h b/riscv/insns/pnclipru_hs.h index d4f82e88..7c74deb6 100644 --- a/riscv/insns/pnclipru_hs.h +++ b/riscv/insns/pnclipru_hs.h @@ -9,5 +9,5 @@ P_NARROW_RD_RS1_ULOOP(16, 32, { uint32_t roundbit = (p_rs1 >> (shamt - 1)) & 1; result = shifted + roundbit; } - p_rd = P_USAT_FULL(16, (sreg_t)result); -}) \ No newline at end of file + p_rd = P_USAT_FULL(16, result); +}) diff --git a/riscv/insns/pnclipu_bs.h b/riscv/insns/pnclipu_bs.h index af10838c..f4e1f1ea 100644 --- a/riscv/insns/pnclipu_bs.h +++ b/riscv/insns/pnclipu_bs.h @@ -1,4 +1,4 @@ require_rv32; P_NARROW_RD_RS1_ULOOP(8, 16, { - p_rd = P_USAT_FULL(8, (sreg_t)(p_rs1 >> (P_UFIELD(RS2, 0, 8) & 0xF))); -}) \ No newline at end of file + p_rd = P_USAT_FULL(8, p_rs1 >> (P_UFIELD(RS2, 0, 8) & 0xF)); +}) diff --git a/riscv/insns/pnclipu_hs.h b/riscv/insns/pnclipu_hs.h index 377bd407..6514f3ef 100644 --- a/riscv/insns/pnclipu_hs.h +++ b/riscv/insns/pnclipu_hs.h @@ -1,4 +1,4 @@ require_rv32; P_NARROW_RD_RS1_ULOOP(16, 32, { - p_rd = P_USAT_FULL(16, (sreg_t)(p_rs1 >> (P_UFIELD(RS2, 0, 16) & 0X1F))); -}) \ No newline at end of file + p_rd = P_USAT_FULL(16, p_rs1 >> (P_UFIELD(RS2, 0, 16) & 0X1F)); +}) diff --git a/riscv/insns/pnclipup_b.h b/riscv/insns/pnclipup_b.h index 0828b676..4679b953 100644 --- a/riscv/insns/pnclipup_b.h +++ b/riscv/insns/pnclipup_b.h @@ -5,7 +5,7 @@ reg_t s_low = RS1; reg_t s_high = RS2; for (int i = 0; i < 8; i++) { reg_t s_h = (i < 4) ? P_UFIELD(s_low, i, 16) : P_UFIELD(s_high, i - 4, 16); - reg_t sat_val = P_USAT_FULL(8, (sreg_t)s_h); + reg_t sat_val = P_USAT_FULL(8, s_h); if (sat_val != s_h) P.set_vxsat(); rd_tmp = set_field(rd_tmp, make_mask64(i * 8, 8), (uint8_t)sat_val); } diff --git a/riscv/insns/pnclipup_h.h b/riscv/insns/pnclipup_h.h index 849831e4..1bb489ee 100644 --- a/riscv/insns/pnclipup_h.h +++ b/riscv/insns/pnclipup_h.h @@ -5,7 +5,7 @@ reg_t s_low = RS1; reg_t s_high = RS2; for (int i = 0; i < 4; i++) { reg_t s_w = (i < 2) ? P_UFIELD(s_low, i, 32) : P_UFIELD(s_high, i - 2, 32); - reg_t sat_val = P_USAT_FULL(16, (sreg_t)s_w); + reg_t sat_val = P_USAT_FULL(16, s_w); if (sat_val != s_w) P.set_vxsat(); rd_tmp = set_field(rd_tmp, make_mask64(i * 16, 16), (uint16_t)sat_val); } diff --git a/riscv/insns/pnclipup_w.h b/riscv/insns/pnclipup_w.h index f2402292..5dffcb16 100644 --- a/riscv/insns/pnclipup_w.h +++ b/riscv/insns/pnclipup_w.h @@ -3,10 +3,10 @@ require_rv64; uint64_t s1 = RS1; uint64_t s2 = RS2; -reg_t sat_w0 = P_USAT_FULL(32, (sreg_t)s1); +reg_t sat_w0 = P_USAT_FULL(32, s1); if (sat_w0 != s1) P.set_vxsat(); -reg_t sat_w1 = P_USAT_FULL(32, (sreg_t)s2); +reg_t sat_w1 = P_USAT_FULL(32, s2); if (sat_w1 != s2) P.set_vxsat(); WRITE_RD(((uint64_t)(uint32_t)sat_w1 << 32) | (uint32_t)sat_w0); diff --git a/riscv/p_ext_macros.h b/riscv/p_ext_macros.h index 405fad85..33ec2a78 100644 --- a/riscv/p_ext_macros.h +++ b/riscv/p_ext_macros.h @@ -767,11 +767,10 @@ }) #define P_USAT_FULL(BIT, R) ({ \ - sreg_t _pusatf_in = (R); \ - sreg_t _pusatf_out; \ - if (_pusatf_in < 0) _pusatf_out = 0; \ - else if ((BIT) >= 64) _pusatf_out = _pusatf_in; \ - else if (_pusatf_in > (sreg_t)((reg_t(1) << (BIT)) - 1)) _pusatf_out = (sreg_t)((reg_t(1) << (BIT)) - 1); \ + reg_t _pusatf_in = (R); \ + reg_t _pusatf_out; \ + if ((BIT) == 64) _pusatf_out = _pusatf_in; \ + else if (_pusatf_in > (reg_t(1) << (BIT)) - 1) _pusatf_out = (reg_t(1) << (BIT)) - 1; \ else _pusatf_out = _pusatf_in; \ if (_pusatf_out != _pusatf_in) P.set_vxsat(); \ _pusatf_out; \ @@ -801,4 +800,4 @@ } \ WRITE_P_RD_PAIR(rd_tmp); -#endif \ No newline at end of file +#endif From 8b5f2b21588b40e090cc304a436b999f085c4b37 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 22 Jul 2026 19:22:42 -0700 Subject: [PATCH 2/2] Remove redundant set_vxsat calls Signed-off-by: Andrew Waterman --- riscv/insns/pnclipp_b.h | 1 - riscv/insns/pnclipp_h.h | 1 - riscv/insns/pnclipp_w.h | 3 --- riscv/insns/pnclipup_b.h | 1 - riscv/insns/pnclipup_h.h | 1 - riscv/insns/pnclipup_w.h | 3 --- 6 files changed, 10 deletions(-) diff --git a/riscv/insns/pnclipp_b.h b/riscv/insns/pnclipp_b.h index 582096e6..060a22d9 100644 --- a/riscv/insns/pnclipp_b.h +++ b/riscv/insns/pnclipp_b.h @@ -6,7 +6,6 @@ reg_t s_high = RS2; for (int i = 0; i < 8; i++) { sreg_t s_h = (i < 4) ? P_FIELD(s_low, i, 16) : P_FIELD(s_high, i - 4, 16); sreg_t sat_val = P_SAT(8, s_h); - if (sat_val != s_h) P.set_vxsat(); rd_tmp = set_field(rd_tmp, make_mask64(i * 8, 8), (uint8_t)sat_val); } WRITE_RD(rd_tmp); diff --git a/riscv/insns/pnclipp_h.h b/riscv/insns/pnclipp_h.h index 3c8812c1..c03b68f6 100644 --- a/riscv/insns/pnclipp_h.h +++ b/riscv/insns/pnclipp_h.h @@ -6,7 +6,6 @@ reg_t s_high = RS2; for (int i = 0; i < 4; i++) { sreg_t s_w = (i < 2) ? P_FIELD(s_low, i, 32) : P_FIELD(s_high, i - 2, 32); sreg_t sat_val = P_SAT(16, s_w); - if (sat_val != s_w) P.set_vxsat(); rd_tmp = set_field(rd_tmp, make_mask64(i * 16, 16), (uint16_t)sat_val); } WRITE_RD(rd_tmp); diff --git a/riscv/insns/pnclipp_w.h b/riscv/insns/pnclipp_w.h index 49729eaa..a8662f40 100644 --- a/riscv/insns/pnclipp_w.h +++ b/riscv/insns/pnclipp_w.h @@ -4,10 +4,7 @@ int64_t s1 = (int64_t)RS1; int64_t s2 = (int64_t)RS2; sreg_t sat_w0 = P_SAT(32, s1); -if (sat_w0 != s1) P.set_vxsat(); - sreg_t sat_w1 = P_SAT(32, s2); -if (sat_w1 != s2) P.set_vxsat(); WRITE_RD(((uint64_t)(uint32_t)sat_w1 << 32) | (uint32_t)sat_w0); diff --git a/riscv/insns/pnclipup_b.h b/riscv/insns/pnclipup_b.h index 4679b953..1d36b095 100644 --- a/riscv/insns/pnclipup_b.h +++ b/riscv/insns/pnclipup_b.h @@ -6,7 +6,6 @@ reg_t s_high = RS2; for (int i = 0; i < 8; i++) { reg_t s_h = (i < 4) ? P_UFIELD(s_low, i, 16) : P_UFIELD(s_high, i - 4, 16); reg_t sat_val = P_USAT_FULL(8, s_h); - if (sat_val != s_h) P.set_vxsat(); rd_tmp = set_field(rd_tmp, make_mask64(i * 8, 8), (uint8_t)sat_val); } WRITE_RD(rd_tmp); diff --git a/riscv/insns/pnclipup_h.h b/riscv/insns/pnclipup_h.h index 1bb489ee..a18d9dae 100644 --- a/riscv/insns/pnclipup_h.h +++ b/riscv/insns/pnclipup_h.h @@ -6,7 +6,6 @@ reg_t s_high = RS2; for (int i = 0; i < 4; i++) { reg_t s_w = (i < 2) ? P_UFIELD(s_low, i, 32) : P_UFIELD(s_high, i - 2, 32); reg_t sat_val = P_USAT_FULL(16, s_w); - if (sat_val != s_w) P.set_vxsat(); rd_tmp = set_field(rd_tmp, make_mask64(i * 16, 16), (uint16_t)sat_val); } WRITE_RD(rd_tmp); diff --git a/riscv/insns/pnclipup_w.h b/riscv/insns/pnclipup_w.h index 5dffcb16..7eb17c60 100644 --- a/riscv/insns/pnclipup_w.h +++ b/riscv/insns/pnclipup_w.h @@ -4,10 +4,7 @@ uint64_t s1 = RS1; uint64_t s2 = RS2; reg_t sat_w0 = P_USAT_FULL(32, s1); -if (sat_w0 != s1) P.set_vxsat(); - reg_t sat_w1 = P_USAT_FULL(32, s2); -if (sat_w1 != s2) P.set_vxsat(); WRITE_RD(((uint64_t)(uint32_t)sat_w1 << 32) | (uint32_t)sat_w0);