From 4cd9301da6b26984247ada52115dcfbd866a8388 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 29 Jul 2020 20:26:39 +1000 Subject: [PATCH] FPU: Implement fsel Signed-off-by: Paul Mackerras --- decode1.vhdl | 1 + fpu.vhdl | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/decode1.vhdl b/decode1.vhdl index c0c3465..09aaf91 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -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 diff --git a/fpu.vhdl b/fpu.vhdl index fee1776..59e6f5d 100644 --- a/fpu.vhdl +++ b/fpu.vhdl @@ -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; -- 2.30.2