From fb71f62b835d7e744a71ee85d2b7198fca8fac1c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 6 Dec 2025 20:53:38 +1100 Subject: [PATCH] FPU: Round finite special-case results to single precision if required When a special case is detected, such as a zero operand to an add, and the operation is a single-precision operation such as fadds, we need to round the result to single precision instead of just returning the relevant input operand unmodified. This accomplishes that by going to DO_FRSP_2 state from the special-case code for single-precision operations that return a finite floating-point result. Signed-off-by: Paul Mackerras --- fpu.vhdl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fpu.vhdl b/fpu.vhdl index 05acf3b..a7f2495 100644 --- a/fpu.vhdl +++ b/fpu.vhdl @@ -1606,9 +1606,9 @@ begin rs_con2 <= RSCON2_MINEXP; rs_neg2 <= '1'; set_x := '1'; -- uses r.r and r.shift - if r.b.exponent < to_signed(-126, EXP_BITS) then + if r.result_exp < to_signed(-126, EXP_BITS) then v.state := ROUND_UFLOW; - elsif r.b.exponent > to_signed(127, EXP_BITS) then + elsif r.result_exp > to_signed(127, EXP_BITS) then v.state := ROUND_OFLOW; else v.state := ROUNDING; @@ -3094,7 +3094,6 @@ begin qnan_result := scinfo.qnan_result; if scinfo.immed_result = '1' then -- state machine is in the DO_SPECIAL or DO_FSQRT state here - arith_done := '1'; set_r := '1'; opsel_r <= RES_MISC; opsel_sel <= scinfo.result_sel; @@ -3104,8 +3103,15 @@ begin else misc_sel <= "110"; end if; + arith_done := '1'; else misc_sel <= "111"; + if r.single_prec = '1' and scinfo.result_class = FINITE and r.int_result = '0' then + -- we have to do the equivalent of frsp on the result + v.state := DO_FRSP_2; + else + arith_done := '1'; + end if; end if; rsgn_op := scinfo.rsgn_op; v.result_class := scinfo.result_class;