1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-04-14 15:34:56 +00:00

FPU: Implement fsel

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
Paul Mackerras
2020-07-29 20:26:39 +10:00
parent 4ad5ab9203
commit 4cd9301da6
2 changed files with 22 additions and 0 deletions

View File

@@ -474,6 +474,7 @@ architecture behaviour of decode1 is
2#0010# => (FPU, OP_FPOP, FRA, FRB, NONE, FRT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- fdiv
2#0100# => (FPU, OP_FPOP, FRA, FRB, NONE, FRT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- fsub
2#0101# => (FPU, OP_FPOP, FRA, FRB, NONE, FRT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- fadd
2#0111# => (FPU, OP_FPOP, FRA, FRB, FRC, FRT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- fsel
2#1000# => (FPU, OP_FPOP, NONE, FRB, NONE, FRT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- fre
2#1001# => (FPU, OP_FPOP, FRA, NONE, FRC, FRT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- fmul
others => illegal_inst

View File

@@ -42,6 +42,7 @@ architecture behaviour of fpu is
DO_FRSP, DO_FRI,
DO_FADD, DO_FMUL, DO_FDIV,
DO_FRE,
DO_FSEL,
FRI_1,
ADD_SHIFT, ADD_2, ADD_3,
MULT_1,
@@ -641,6 +642,8 @@ begin
v.state := DO_FDIV;
when "10100" | "10101" =>
v.state := DO_FADD;
when "10111" =>
v.state := DO_FSEL;
when "11000" =>
v.state := DO_FRE;
when "11001" =>
@@ -1045,6 +1048,24 @@ begin
arith_done := '1';
end if;
when DO_FSEL =>
opsel_a <= AIN_A;
v.fpscr(FPSCR_FR) := '0';
v.fpscr(FPSCR_FI) := '0';
if r.a.class = ZERO or (r.a.negative = '0' and r.a.class /= NAN) then
v.result_sign := r.c.negative;
v.result_exp := r.c.exponent;
v.result_class := r.c.class;
opsel_a <= AIN_C;
else
v.result_sign := r.b.negative;
v.result_exp := r.b.exponent;
v.result_class := r.b.class;
opsel_a <= AIN_B;
end if;
v.quieten_nan := '0';
arith_done := '1';
when DO_FRE =>
opsel_a <= AIN_B;
v.result_class := r.b.class;