mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-13 15:18:09 +00:00
FPU: Fix behaviour of fdiv with denormalized divisor
Renormalization of the divisor for fdiv[s] was adjusting the result exponent in the wrong direction, making the result smaller in magnitude than it should be by a power of 2. Fix this by negating r.shift in the RENORM_B2 state and then subtracting it in the LOOKUP cycle. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
parent
59a7996f1c
commit
51954671f3
19
fpu.vhdl
19
fpu.vhdl
@ -1817,8 +1817,17 @@ begin
|
||||
|
||||
when RENORM_B2 =>
|
||||
set_b := '1';
|
||||
re_sel2 <= REXP2_NE;
|
||||
re_set_result <= '1';
|
||||
-- For fdiv, we need to increase result_exp by shift rather
|
||||
-- than decreasing it as for fre/frsqrte and fsqrt.
|
||||
-- We do that by negating r.shift in this cycle and then
|
||||
-- setting result_exp to new_exp in the next cycle
|
||||
if r.use_a = '1' then
|
||||
rs_sel1 <= RSH1_S;
|
||||
rs_neg1 <= '1';
|
||||
else
|
||||
re_sel2 <= REXP2_NE;
|
||||
re_set_result <= '1';
|
||||
end if;
|
||||
v.opsel_a := AIN_B;
|
||||
v.state := LOOKUP;
|
||||
|
||||
@ -2038,6 +2047,12 @@ begin
|
||||
when LOOKUP =>
|
||||
-- r.opsel_a = AIN_B
|
||||
-- wait one cycle for inverse_table[B] lookup
|
||||
-- if this is a division, compute exponent
|
||||
-- (see comment on RENORM_B2 above)
|
||||
if r.use_a = '1' then
|
||||
re_sel2 <= REXP2_NE;
|
||||
re_set_result <= '1';
|
||||
end if;
|
||||
v.first := '1';
|
||||
if r.insn(4) = '0' then
|
||||
if r.insn(3) = '0' then
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user