From f8a11420cace770513c2645c9e670090f895bfa9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 13 Dec 2025 11:31:31 +1100 Subject: [PATCH] FPU: Check for rounding overflow in 32-bit convert-to-integer operations Without this, rounding a value of 0xFFFFFFFF up, giving 0x100000000, will yield an incorrect result of zero. Signed-off-by: Paul Mackerras --- fpu.vhdl | 8 ++++++-- tests/fpu/fpu.c | 3 +++ tests/test_fpu.bin | Bin 34496 -> 34616 bytes 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/fpu.vhdl b/fpu.vhdl index 272e475..751b400 100644 --- a/fpu.vhdl +++ b/fpu.vhdl @@ -2356,10 +2356,13 @@ begin -- Check for possible overflows case r.insn(9 downto 8) is when "00" => -- fctiw[z] + -- check bit 32 in case of rounding overflow need_check := r.r(31) or (r.r(30) and not r.result_sign); when "01" => -- fctiwu[z] - need_check := r.r(31); + -- check bit 32 in case of rounding overflow + need_check := r.r(31) or r.r(31); when "10" => -- fctid[z] + -- can't get rounding overflow for 64-bit conversion need_check := r.r(63) or (r.r(62) and not r.result_sign); when others => -- fctidu[z] need_check := r.r(63); @@ -2380,7 +2383,8 @@ begin msb := r.r(63); end if; if (r.insn(8) = '0' and msb /= r.result_sign) or - (r.insn(8) = '1' and msb /= '1') then + (r.insn(8) = '1' and msb /= '1') or + (r.insn(9) = '0' and r.r(32) /= r.result_sign) then v.state := INT_OFLOW; else if r.fpscr(FPSCR_FI) = '1' then diff --git a/tests/fpu/fpu.c b/tests/fpu/fpu.c index 535d77a..7a4b935 100644 --- a/tests/fpu/fpu.c +++ b/tests/fpu/fpu.c @@ -756,6 +756,8 @@ struct cvtivals { { 0x7ff923456789abcd, 0x8000000000000000, 0, 0x80000000, 0, { 1, 1, 1, 1 } }, { 0xfff923456789abcd, 0x8000000000000000, 0, 0x80000000, 0, { 1, 1, 1, 1 } }, { 0xbfd123456789abcd, 0, 0, 0, 0, {0, 0, 0, 0} }, + { 0x41effffffff00081, 0x100000000, 0x100000000, 0x7fffffff, 0xffffffff, { 0, 0, 1, 1 } }, + { 0xc1e0000000000000, 0xffffffff80000000, 0x0000000000000000, 0x80000000, 0x00000000, { 0, 1, 0, 1 } }, }; #define GET_VXCVI() ((get_fpscr() >> 8) & 1) @@ -830,6 +832,7 @@ struct cvtivals cvtizvals[] = { { 0xfff0000000000000, 0x8000000000000000, 0, 0x80000000, 0, { 1, 1, 1, 1 } }, { 0x7ff923456789abcd, 0x8000000000000000, 0, 0x80000000, 0, { 1, 1, 1, 1 } }, { 0xfff923456789abcd, 0x8000000000000000, 0, 0x80000000, 0, { 1, 1, 1, 1 } }, + { 0xc1e0000000000000, 0xffffffff80000000, 0x0000000000000000, 0x80000000, 0x00000000, { 0, 1, 0, 1 } }, }; int test10(long arg) diff --git a/tests/test_fpu.bin b/tests/test_fpu.bin index 3d6dcce8e98d9d097e26d3664fb1a4b82f2d3d1a..0ae6099b6e9a2a79e0396313b794f59f4f938822 100755 GIT binary patch delta 3934 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 E4@ZF3`2YX_