diff --git a/fpu.vhdl b/fpu.vhdl index 7d8060a..48c021d 100644 --- a/fpu.vhdl +++ b/fpu.vhdl @@ -1931,7 +1931,6 @@ begin v.instr_done := '1'; when MULT_1 => - f_to_multiply.valid <= r.first; opsel_r <= RES_MULT; set_r := '1'; opsel_s <= S_MULT; @@ -2022,25 +2021,18 @@ begin v.state := FMADD_6; when FMADD_6 => - -- r.shift = UNIT_BIT (or 0, but only if r is now nonzero) + -- r.shift = UNIT_BIT set_r := '0'; opsel_r <= RES_SHIFT; re_sel2 <= REXP2_NE; - rs_norm <= '1'; - rcls_op <= RCLS_TZERO; if (r.r(UNIT_BIT + 2) or r_hi_nz or r_lo_nz or (or (r.r(DP_LSB - 1 downto 0)))) = '0' then - -- S = 0 case is handled by RCLS_TZERO logic, otherwise... - -- R is all zeroes but there are non-zero bits in S + -- R is all zeroes but there may be non-zero bits in S -- so shift them into R and set S to 0 set_r := '1'; re_set_result <= '1'; set_s := '1'; - v.state := FINISH; - elsif r.r(UNIT_BIT + 2 downto UNIT_BIT) = "001" then - v.state := FINISH; - else - v.state := NORMALIZE; end if; + v.state := FINISH; when DIV_2 => -- compute Y = inverse_table[B] (when count=0); P = 2 - B * Y @@ -3197,7 +3189,7 @@ begin when others => end case; when RCLS_TZERO => - if or (r.r(UNIT_BIT + 2 downto 0)) = '0' and s_nz = '0' then + if or (r.r(UNIT_BIT + 2 downto 0)) = '0' then v.result_class := ZERO; arith_done := '1'; end if; diff --git a/tests/fpu/fpu.c b/tests/fpu/fpu.c index 89fb44f..ccf07f8 100644 --- a/tests/fpu/fpu.c +++ b/tests/fpu/fpu.c @@ -1618,6 +1618,8 @@ struct fmavals { /* from random exec tests */ { 0x43eff79000000000, 0x00000000000000ff, 0x0000000000000081, FPS_RN_CEIL, 0x014fd79870000001, 0x014fd79870000000, 0x814fd79870000001, 0x814fd79870000000 }, + { 0x00000000ffffffff, 0x1fc771af627f62ab, 0x8000000000000000, FPS_RN_ZERO, + 0x0000000000000000, 0x0000000000000000, 0x8000000000000000, 0x8000000000000000 }, }; int test23(long arg) diff --git a/tests/test_fpu.bin b/tests/test_fpu.bin index e6a21b8..2a7845b 100755 Binary files a/tests/test_fpu.bin and b/tests/test_fpu.bin differ