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>
pull/382/head
Paul Mackerras 3 years ago
parent 7a60c118ed
commit 03ca9b5dd5

@ -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);

Loading…
Cancel
Save