mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
FPU: Set FPRF correctly on multiply result that underflows
rcls_op being set to RCLS_TZERO was not detecting a zero result after rounding for a multiply result that underflows, because S still had low bits of the product. To fix this, remove the 's_nz = 0' from the RCLS_TZERO test. We can't then use this test in the FMADD_6 state, but we really shouldn't be testing for zero there, before rounding, so remove that. Also simplify FMADD_6 state by not setting rs_norm and going always to FINISH state rather than going to NORMALIZE state. Add a test for this case (actually a fmadd with B=0). While here, remove a pointless assignment to f_to_multiply.valid in MULT_1 state, since r.first is never set here. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
parent
b122577a4e
commit
f631dcd700
16
fpu.vhdl
16
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;
|
||||
|
||||
@ -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)
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user