mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-02-03 15:12:52 +00:00
FPU: Minor fix and simplifications
In preparation for an explicit exponent data path. The fix is that fre[s] needs to negate the exponent after renomalization rather than before, otherwise the exponent adjustment done by the renormalization is in the wrong direction. Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
37
fpu.vhdl
37
fpu.vhdl
@@ -56,7 +56,7 @@ architecture behaviour of fpu is
|
||||
ADD_1, ADD_SHIFT, ADD_2, ADD_3,
|
||||
CMP_1, CMP_2,
|
||||
MULT_1,
|
||||
FMADD_1, FMADD_2, FMADD_3,
|
||||
FMADD_0, FMADD_1, FMADD_2, FMADD_3,
|
||||
FMADD_4, FMADD_5, FMADD_6,
|
||||
LOOKUP,
|
||||
DIV_2, DIV_3, DIV_4, DIV_5, DIV_6,
|
||||
@@ -1538,9 +1538,9 @@ begin
|
||||
v.fpscr(FPSCR_FR) := '0';
|
||||
v.fpscr(FPSCR_FI) := '0';
|
||||
v.use_b := '1';
|
||||
v.result_exp := r.b.exponent;
|
||||
case r.b.class is
|
||||
when FINITE =>
|
||||
v.result_exp := - r.b.exponent;
|
||||
if r.b.mantissa(UNIT_BIT) = '0' then
|
||||
v.state := RENORM_B;
|
||||
else
|
||||
@@ -1600,7 +1600,7 @@ begin
|
||||
-- else AIN_B
|
||||
v.result_sign := r.a.negative;
|
||||
v.result_class := r.a.class;
|
||||
v.result_exp := r.a.exponent;
|
||||
v.result_exp := r.a.exponent + r.c.exponent;
|
||||
v.fpscr(FPSCR_FR) := '0';
|
||||
v.fpscr(FPSCR_FI) := '0';
|
||||
v.use_a := '1';
|
||||
@@ -1610,8 +1610,6 @@ begin
|
||||
if r.a.class = FINITE and r.c.class = FINITE and
|
||||
(r.b.class = FINITE or r.b.class = ZERO) then
|
||||
v.is_subtract := not is_add;
|
||||
mulexp := r.a.exponent + r.c.exponent;
|
||||
v.result_exp := mulexp;
|
||||
-- Make sure A and C are normalized
|
||||
if r.a.mantissa(UNIT_BIT) = '0' then
|
||||
v.state := RENORM_A;
|
||||
@@ -1627,15 +1625,10 @@ begin
|
||||
-- addend is bigger, do multiply first
|
||||
v.result_sign := not (r.b.negative xor r.insn(1) xor r.insn(2));
|
||||
f_to_multiply.valid <= '1';
|
||||
v.state := FMADD_1;
|
||||
v.state := FMADD_0;
|
||||
else
|
||||
-- product is bigger, shift B right and use it as the
|
||||
-- addend to the multiplier
|
||||
v.shift := r.b.exponent - mulexp + to_signed(64, EXP_BITS);
|
||||
-- for subtract, multiplier does B - A * C
|
||||
v.result_sign := not (r.a.negative xor r.c.negative xor r.insn(2) xor is_add);
|
||||
v.result_exp := r.b.exponent;
|
||||
v.state := FMADD_2;
|
||||
-- product is bigger, shift B first
|
||||
v.state := FMADD_1;
|
||||
end if;
|
||||
else
|
||||
if r.a.class = NAN or r.b.class = NAN or r.c.class = NAN then
|
||||
@@ -1715,11 +1708,7 @@ begin
|
||||
|
||||
when RENORM_B2 =>
|
||||
set_b := '1';
|
||||
if r.is_sqrt = '0' then
|
||||
v.result_exp := r.result_exp + r.shift;
|
||||
else
|
||||
v.result_exp := new_exp;
|
||||
end if;
|
||||
v.result_exp := new_exp;
|
||||
v.opsel_a := AIN_B;
|
||||
v.state := LOOKUP;
|
||||
|
||||
@@ -1830,7 +1819,7 @@ begin
|
||||
v.state := FINISH;
|
||||
end if;
|
||||
|
||||
when FMADD_1 =>
|
||||
when FMADD_0 =>
|
||||
-- Addend is bigger here
|
||||
v.result_sign := not (r.b.negative xor r.insn(1) xor r.insn(2));
|
||||
-- note v.shift is at most -2 here
|
||||
@@ -1844,6 +1833,15 @@ begin
|
||||
v.state := ADD_SHIFT;
|
||||
end if;
|
||||
|
||||
when FMADD_1 =>
|
||||
-- product is bigger here
|
||||
-- shift B right and use it as the addend to the multiplier
|
||||
v.shift := r.b.exponent - r.result_exp + to_signed(64, EXP_BITS);
|
||||
-- for subtract, multiplier does B - A * C
|
||||
v.result_sign := r.a.negative xor r.c.negative xor r.insn(2) xor r.is_subtract;
|
||||
v.result_exp := r.b.exponent;
|
||||
v.state := FMADD_2;
|
||||
|
||||
when FMADD_2 =>
|
||||
-- Product is potentially bigger here
|
||||
-- r.shift = addend exp - product exp + 64, r.r = r.b.mantissa
|
||||
@@ -1993,6 +1991,7 @@ begin
|
||||
v.state := FINISH;
|
||||
|
||||
when FRE_1 =>
|
||||
v.result_exp := - r.result_exp;
|
||||
opsel_r <= RES_MISC;
|
||||
misc_sel <= "0111";
|
||||
v.shift := to_signed(1, EXP_BITS);
|
||||
|
||||
Reference in New Issue
Block a user