FPU: Factor out some of the common elements of the DO_* states

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
pull/442/head
Paul Mackerras 1 year ago
parent 2422585e14
commit 4e5f856c55

@ -146,6 +146,7 @@ architecture behaviour of fpu is
exp_cmp : std_ulogic;
madd_cmp : std_ulogic;
add_bsmall : std_ulogic;
is_arith : std_ulogic;
is_addition : std_ulogic;
is_multiply : std_ulogic;
is_inverse : std_ulogic;
@ -176,6 +177,7 @@ architecture behaviour of fpu is
res_sign : std_ulogic;
res_int : std_ulogic;
exec_state : state_t;
cycle_1 : std_ulogic;
end record;

type lookup_table is array(0 to 1023) of std_ulogic_vector(17 downto 0);
@ -880,6 +882,7 @@ begin
is_nan_inf := '0';
is_zero_den := '0';
sign_inv := '0';
v.cycle_1 := e_in.valid;

if r.complete = '1' or r.do_intr = '1' then
v.instr_done := '0';
@ -925,6 +928,7 @@ begin
v.negate := '0';
v.quieten_nan := '1';
v.int_result := '0';
v.is_arith := '0';
case e_in.op is
when OP_FP_ARITH =>
fpin_a := e_in.valid_a;
@ -932,6 +936,7 @@ begin
fpin_c := e_in.valid_c;
v.longmask := e_in.single;
v.fp_rc := e_in.rc;
v.is_arith := '1';
exec_state := arith_decode(to_integer(unsigned(e_in.insn(5 downto 1))));
if e_in.insn(5 downto 1) = "10110" or e_in.insn(5 downto 1) = "11010" then
v.is_sqrt := '1';
@ -1193,6 +1198,11 @@ begin

rsgn_op := RSGN_NOP;

if r.cycle_1 = '1' and r.is_arith = '1' then
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
end if;

case r.state is
when IDLE =>
v.invalid := '0';
@ -1218,8 +1228,6 @@ begin

when DO_NAN_INF =>
-- At least one floating-point operand is infinity or NaN
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
invalid_mul := '0';

if (r.a.class = NAN and r.a.mantissa(QNAN_BIT) = '0') or
@ -1285,8 +1293,6 @@ begin

when DO_ZERO_DEN =>
-- At least one floating point operand is zero or denormalized
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
if (r.use_a = '1' and r.a.class = ZERO) or
(r.use_b = '1' and r.b.class = ZERO and r.is_multiply = '0') or
(r.use_c = '1' and r.c.class = ZERO) then
@ -1559,8 +1565,6 @@ begin
rs_sel1 <= RSH1_B;
rs_con2 <= RSCON2_52;
rs_neg2 <= '1';
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
if r.b.exponent >= to_signed(52, EXP_BITS) then
-- integer already, no rounding required
arith_done := '1';
@ -1577,8 +1581,6 @@ begin
rs_sel1 <= RSH1_B;
rs_con2 <= RSCON2_MINEXP;
rs_neg2 <= '1';
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
set_x := '1';
if r.b.exponent < to_signed(-126, EXP_BITS) then
v.state := ROUND_UFLOW;
@ -1598,8 +1600,6 @@ begin
re_set_result <= '1';
rs_sel1 <= RSH1_B;
rs_neg2 <= '1';
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';

if r.b.exponent >= to_signed(64, EXP_BITS) or
(r.insn(9) = '0' and r.b.exponent >= to_signed(32, EXP_BITS)) then
@ -1630,8 +1630,6 @@ begin
v.result_class := r.b.class;
re_con2 <= RECON2_UNIT;
re_set_result <= '1';
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
if r.b.class = ZERO then
arith_done := '1';
else
@ -1648,8 +1646,6 @@ begin
rs_sel1 <= RSH1_B;
rs_neg1 <= '1';
rs_sel2 <= RSH2_A;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
v.add_bsmall := r.exp_cmp;
v.opsel_a := AIN_B;
if r.exp_cmp = '0' then
@ -1667,8 +1663,6 @@ begin
-- fmul[s]
-- r.opsel_a = AIN_A unless C is denorm and A isn't
v.result_class := r.a.class;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
re_sel1 <= REXP1_A;
re_sel2 <= REXP2_C;
re_set_result <= '1';
@ -1685,8 +1679,6 @@ begin
when DO_FDIV =>
-- r.opsel_a = AIN_A unless B is denorm and A isn't
v.result_class := r.a.class;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
re_sel1 <= REXP1_A;
re_sel2 <= REXP2_B;
re_neg2 <= '1';
@ -1714,8 +1706,6 @@ begin
when DO_FSQRT =>
-- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
re_sel2 <= REXP2_B;
re_set_result <= '1';
if r.b.negative = '1' then
@ -1734,8 +1724,6 @@ begin
when DO_FRE =>
-- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
re_sel2 <= REXP2_B;
re_set_result <= '1';
if r.b.mantissa(UNIT_BIT) = '0' then
@ -1747,8 +1735,6 @@ begin
when DO_FRSQRTE =>
-- r.opsel_a = AIN_B
v.result_class := r.b.class;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
re_sel2 <= REXP2_B;
re_set_result <= '1';
-- set shift to 1
@ -1775,8 +1761,6 @@ begin
re_set_result <= '1';
-- put b.exp into shift
rs_sel1 <= RSH1_B;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
-- Make sure A and C are normalized
if r.a.mantissa(UNIT_BIT) = '0' then
v.state := RENORM_A;

Loading…
Cancel
Save