Browse Source
Merge pull request #2352 from riscv-software-src/fix-2350
Fix PNCLIPUP.W by avoiding signed arithmetic
pull/2353/head
Andrew Waterman
2 weeks ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with
25 additions and
36 deletions
-
riscv/insns/pnclipiu_b.h
-
riscv/insns/pnclipiu_h.h
-
riscv/insns/pnclipp_b.h
-
riscv/insns/pnclipp_h.h
-
riscv/insns/pnclipp_w.h
-
riscv/insns/pnclipriu_b.h
-
riscv/insns/pnclipriu_h.h
-
riscv/insns/pnclipru_bs.h
-
riscv/insns/pnclipru_hs.h
-
riscv/insns/pnclipu_bs.h
-
riscv/insns/pnclipu_hs.h
-
riscv/insns/pnclipup_b.h
-
riscv/insns/pnclipup_h.h
-
riscv/insns/pnclipup_w.h
-
riscv/p_ext_macros.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())); |
|
|
|
p_rd = P_USAT_FULL(8, p_rs1 >> insn.shamth()); |
|
|
|
}) |
|
|
|
@ -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())); |
|
|
|
p_rd = P_USAT_FULL(16, p_rs1 >> insn.shamtw()); |
|
|
|
}) |
|
|
|
@ -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); |
|
|
|
|
|
|
|
@ -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); |
|
|
|
|
|
|
|
@ -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); |
|
|
|
|
|
|
|
|
|
|
|
@ -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); |
|
|
|
p_rd = P_USAT_FULL(8, result); |
|
|
|
}) |
|
|
|
@ -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); |
|
|
|
p_rd = P_USAT_FULL(16, result); |
|
|
|
}) |
|
|
|
@ -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); |
|
|
|
p_rd = P_USAT_FULL(8, result); |
|
|
|
}) |
|
|
|
@ -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); |
|
|
|
p_rd = P_USAT_FULL(16, result); |
|
|
|
}) |
|
|
|
@ -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))); |
|
|
|
p_rd = P_USAT_FULL(8, p_rs1 >> (P_UFIELD(RS2, 0, 8) & 0xF)); |
|
|
|
}) |
|
|
|
@ -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))); |
|
|
|
p_rd = P_USAT_FULL(16, p_rs1 >> (P_UFIELD(RS2, 0, 16) & 0X1F)); |
|
|
|
}) |
|
|
|
@ -5,8 +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); |
|
|
|
if (sat_val != s_h) P.set_vxsat(); |
|
|
|
reg_t sat_val = P_USAT_FULL(8, s_h); |
|
|
|
rd_tmp = set_field(rd_tmp, make_mask64(i * 8, 8), (uint8_t)sat_val); |
|
|
|
} |
|
|
|
WRITE_RD(rd_tmp); |
|
|
|
|
|
|
|
@ -5,8 +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); |
|
|
|
if (sat_val != s_w) P.set_vxsat(); |
|
|
|
reg_t sat_val = P_USAT_FULL(16, s_w); |
|
|
|
rd_tmp = set_field(rd_tmp, make_mask64(i * 16, 16), (uint16_t)sat_val); |
|
|
|
} |
|
|
|
WRITE_RD(rd_tmp); |
|
|
|
|
|
|
|
@ -3,11 +3,8 @@ require_rv64; |
|
|
|
uint64_t s1 = RS1; |
|
|
|
uint64_t s2 = RS2; |
|
|
|
|
|
|
|
reg_t sat_w0 = P_USAT_FULL(32, (sreg_t)s1); |
|
|
|
if (sat_w0 != s1) P.set_vxsat(); |
|
|
|
|
|
|
|
reg_t sat_w1 = P_USAT_FULL(32, (sreg_t)s2); |
|
|
|
if (sat_w1 != s2) P.set_vxsat(); |
|
|
|
reg_t sat_w0 = P_USAT_FULL(32, s1); |
|
|
|
reg_t sat_w1 = P_USAT_FULL(32, s2); |
|
|
|
|
|
|
|
WRITE_RD(((uint64_t)(uint32_t)sat_w1 << 32) | (uint32_t)sat_w0); |
|
|
|
|
|
|
|
|
|
|
|
@ -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; \ |
|
|
|
|